libpqxx
field.hxx
1
13#ifndef PQXX_H_FIELD
14#define PQXX_H_FIELD
15
16#include "pqxx/compiler-public.hxx"
17#include "pqxx/compiler-internal-pre.hxx"
18#include "pqxx/internal/type_utils.hxx"
19
20#if defined(PQXX_HAVE_OPTIONAL)
21#include <optional>
22
23/* Use std::experimental::optional as a fallback for std::optional, if
24 * present.
25 *
26 * This may break compilation for some software, if using a libpqxx that was
27 * configured for a different language version. To stop libpqxx headers from
28 * using or supporting std::experimental::optional, define a macro
29 * PQXX_HIDE_EXP_OPTIONAL when building your software.
30 */
31#elif defined(PQXX_HAVE_EXP_OPTIONAL) && !defined(PQXX_HIDE_EXP_OPTIONAL)
32#include <experimental/optional>
33#endif
34
35#include "pqxx/array.hxx"
36#include "pqxx/result.hxx"
37#include "pqxx/strconv.hxx"
38#include "pqxx/types.hxx"
39
40
41// Methods tested in eg. test module test01 are marked with "//[t01]".
42
43namespace pqxx
44{
46
49class PQXX_LIBEXPORT field
50{
51public:
53
55
59 field(const row &R, row_size_type C) noexcept; //[t01]
60
66
82 bool operator==(const field &) const; //[t75]
83
85
87 bool operator!=(const field &rhs) const //[t82]
88 {return not operator==(rhs);}
90
96 const char *name() const; //[t11]
97
99 oid type() const; //[t07]
100
102 oid table() const; //[t02]
103
104 row_size_type num() const { return col(); } //[t82]
105
107 row_size_type table_column() const; //[t93]
109
115
120 const char *c_str() const; //[t02]
121
123 bool is_null() const noexcept; //[t12]
124
126
129 size_type size() const noexcept; //[t11]
130
132
135 template<typename T> auto to(T &Obj) const //[t03]
136 -> typename std::enable_if<(
137 not std::is_pointer<T>::value
138 or std::is_same<T, const char*>::value
139 ), bool>::type
140 {
141 const char *const bytes = c_str();
142 if (bytes[0] == '\0' and is_null()) return false;
143 from_string(bytes, Obj);
144 return true;
145 }
146
148 template<typename T> bool operator>>(T &Obj) const //[t07]
149 { return to(Obj); }
150
152
155 template<typename T> auto to(T &Obj, const T &Default) const //[t12]
156 -> typename std::enable_if<(
157 not std::is_pointer<T>::value
158 or std::is_same<T, const char*>::value
159 ), bool>::type
160 {
161 const bool NotNull = to(Obj);
162 if (not NotNull) Obj = Default;
163 return NotNull;
164 }
165
167
170 template<typename T> T as(const T &Default) const //[t01]
171 {
172 T Obj;
173 to(Obj, Default);
174 return Obj;
175 }
176
178
183 template<typename T> T as() const //[t45]
184 {
185 T Obj;
186 if (not to(Obj)) Obj = string_traits<T>::null();
187 return Obj;
188 }
189
191
195 template<typename T, template<typename> class O
196#if defined(PQXX_HAVE_OPTIONAL)
197 = std::optional
198#elif defined(PQXX_HAVE_EXP_OPTIONAL) && !defined(PQXX_HIDE_EXP_OPTIONAL)
199 = std::experimental::optional
200#endif
201 > constexpr O<T> get() const { return as<O<T>>(); }
202
204
211 { return array_parser{c_str(), m_home.m_encoding}; }
213
214
215protected:
216 const result &home() const noexcept { return m_home; }
217 size_t idx() const noexcept { return m_row; }
218 row_size_type col() const noexcept { return row_size_type(m_col); }
219
224 long m_col;
225
226private:
227 result m_home;
228 size_t m_row;
229};
230
231
233template<>
234inline bool field::to<std::string>(std::string &Obj) const
235{
236 const char *const bytes = c_str();
237 if (bytes[0] == '\0' and is_null()) return false;
238 Obj = std::string{bytes, size()};
239 return true;
240}
241
243
248template<>
249inline bool field::to<const char *>(const char *&Obj) const
250{
251 if (is_null()) return false;
252 Obj = c_str();
253 return true;
254}
255
256
257template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
259 public std::basic_streambuf<CHAR, TRAITS>
260{
261public:
262 using char_type = CHAR;
263 using traits_type = TRAITS;
264 using int_type = typename traits_type::int_type;
265 using pos_type = typename traits_type::pos_type;
266 using off_type = typename traits_type::off_type;
267 using openmode = std::ios::openmode;
268 using seekdir = std::ios::seekdir;
269
270 explicit field_streambuf(const field &F) : //[t74]
271 m_field{F}
272 {
273 initialize();
274 }
275
276protected:
277 virtual int sync() override { return traits_type::eof(); }
278
279protected:
281 { return traits_type::eof(); }
283 {return traits_type::eof();}
284 virtual int_type overflow(int_type) override
285 { return traits_type::eof(); }
286 virtual int_type underflow() override
287 { return traits_type::eof(); }
288
289private:
290 const field &m_field;
291
292 int_type initialize()
293 {
294 char_type *G =
295 reinterpret_cast<char_type *>(const_cast<char *>(m_field.c_str()));
296 this->setg(G, G, G + m_field.size());
297 return int_type(m_field.size());
298 }
299};
300
301
303
311template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
313 public std::basic_istream<CHAR, TRAITS>
314{
315 using super = std::basic_istream<CHAR, TRAITS>;
316
317public:
318 using char_type = CHAR;
319 using traits_type = TRAITS;
320 using int_type = typename traits_type::int_type;
321 using pos_type = typename traits_type::pos_type;
322 using off_type = typename traits_type::off_type;
323
324 basic_fieldstream(const field &F) : super{nullptr}, m_buf{F}
325 { super::init(&m_buf); }
326
327private:
329};
330
332
334
354template<typename CHAR>
355inline std::basic_ostream<CHAR> &operator<<(
356 std::basic_ostream<CHAR> &S, const field &F) //[t46]
357{
358 S.write(F.c_str(), std::streamsize(F.size()));
359 return S;
360}
361
362
364template<typename T>
365inline void from_string(const field &F, T &Obj) //[t46]
366 { from_string(F.c_str(), Obj, F.size()); }
367
369template<> PQXX_LIBEXPORT std::string to_string(const field &Obj); //[t74]
370
371} // namespace pqxx
372#include "pqxx/compiler-internal-post.hxx"
373#endif
STL namespace.
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:26
std::basic_ostream< CHAR > & operator<<(std::basic_ostream< CHAR > &S, const field &F)
Write a result field to any type of stream.
Definition: field.hxx:355
void from_string(const field &F, T &Obj)
Convert a field's string contents to another type.
Definition: field.hxx:365
std::string to_string(const field &Obj)
Convert a field to a string.
Definition: result.cxx:451
std::size_t field_size_type
Number of bytes in a field of database data.
Definition: types.hxx:30
unsigned int row_size_type
Number of fields in a row of database data.
Definition: types.hxx:24
Low-level array parser.
Definition: array.hxx:47
Reference to a field in a result set.
Definition: field.hxx:50
row_size_type num() const
Definition: field.hxx:104
row_size_type col() const noexcept
Definition: field.hxx:218
size_type size() const noexcept
Return number of bytes taken up by the field's value.
Definition: field.cxx:74
long m_col
Definition: field.hxx:224
T as(const T &Default) const
Return value as object of given type, or Default if null.
Definition: field.hxx:170
field_size_type size_type
Definition: field.hxx:52
bool operator>>(T &Obj) const
Read value into Obj; or leave Obj untouched and return false if null.
Definition: field.hxx:148
array_parser as_array() const
Parse the field as an SQL array.
Definition: field.hxx:210
const result & home() const noexcept
Definition: field.hxx:216
T as() const
Return value as object of given type, or throw exception if null.
Definition: field.hxx:183
auto to(T &Obj, const T &Default) const -> typename std::enable_if<(not std::is_pointer< T >::value or std::is_same< T, const char * >::value), bool >::type
Read value into Obj; or use Default & return false if null.
Definition: field.hxx:155
const char * c_str() const
Read as plain C string.
Definition: field.cxx:62
bool is_null() const noexcept
Is this field's value null?
Definition: field.cxx:68
constexpr O< T > get() const
Return value wrapped in some optional type (empty for nulls)
Definition: field.hxx:201
size_t idx() const noexcept
Definition: field.hxx:217
bool operator!=(const field &rhs) const
Byte-by-byte comparison (all nulls are considered equal)
Definition: field.hxx:87
Definition: field.hxx:260
TRAITS traits_type
Definition: field.hxx:263
typename traits_type::off_type off_type
Definition: field.hxx:266
virtual pos_type seekoff(off_type, seekdir, openmode) override
Definition: field.hxx:280
virtual pos_type seekpos(pos_type, openmode) override
Definition: field.hxx:282
std::ios::openmode openmode
Definition: field.hxx:267
virtual int_type overflow(int_type) override
Definition: field.hxx:284
field_streambuf(const field &F)
Definition: field.hxx:270
typename traits_type::pos_type pos_type
Definition: field.hxx:265
virtual int sync() override
Definition: field.hxx:277
typename traits_type::int_type int_type
Definition: field.hxx:264
virtual int_type underflow() override
Definition: field.hxx:286
CHAR char_type
Definition: field.hxx:262
std::ios::seekdir seekdir
Definition: field.hxx:268
Input stream that gets its data from a result field.
Definition: field.hxx:314
TRAITS traits_type
Definition: field.hxx:319
basic_fieldstream(const field &F)
Definition: field.hxx:324
typename traits_type::pos_type pos_type
Definition: field.hxx:321
typename traits_type::off_type off_type
Definition: field.hxx:322
typename traits_type::int_type int_type
Definition: field.hxx:320
CHAR char_type
Definition: field.hxx:318
Result set containing data returned by a query or command.
Definition: result.hxx:70
Reference to one row in a result.
Definition: row.hxx:41
Traits class for use in string conversions.
Definition: strconv.hxx:51