libpqxx  7.3.0
field.hxx
1 /* Definitions for the pqxx::field class.
2  *
3  * pqxx::field refers to a field in a query result.
4  *
5  * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/field 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_FIELD
14 #define PQXX_H_FIELD
15 
16 #include "pqxx/compiler-public.hxx"
17 #include "pqxx/internal/compiler-internal-pre.hxx"
18 
19 #include <optional>
20 
21 #include "pqxx/array.hxx"
22 #include "pqxx/composite.hxx"
23 #include "pqxx/result.hxx"
24 #include "pqxx/strconv.hxx"
25 #include "pqxx/types.hxx"
26 
27 namespace pqxx
28 {
30 
33 class PQXX_LIBEXPORT field
34 {
35 public:
37 
39 
43  field(row const &r, row_size_type c) noexcept;
44 
45  field() = default;
46 
51 
68  [[nodiscard]] PQXX_PURE bool operator==(field const &) const;
69 
71 
73  [[nodiscard]] PQXX_PURE bool operator!=(field const &rhs) const
74  {
75  return not operator==(rhs);
76  }
78 
83  [[nodiscard]] PQXX_PURE char const *name() const;
85 
87  [[nodiscard]] oid PQXX_PURE type() const;
88 
90  [[nodiscard]] PQXX_PURE oid table() const;
91 
92  PQXX_PURE row_size_type num() const { return col(); }
93 
95  [[nodiscard]] PQXX_PURE row_size_type table_column() const;
97 
102  [[nodiscard]] PQXX_PURE std::string_view view() const
104  {
105  return std::string_view(c_str(), size());
106  }
107 
109 
118  [[nodiscard]] PQXX_PURE char const *c_str() const;
119 
121  [[nodiscard]] PQXX_PURE bool is_null() const noexcept;
122 
124  [[nodiscard]] PQXX_PURE size_type size() const noexcept;
125 
127 
130  template<typename T>
131  auto to(T &obj) const -> typename std::enable_if_t<
132  (not std::is_pointer<T>::value or std::is_same<T, char const *>::value),
133  bool>
134  {
135  if (is_null())
136  {
137  return false;
138  }
139  else
140  {
141  auto const bytes{c_str()};
142  from_string(bytes, obj);
143  return true;
144  }
145  }
146 
148 
153  template<typename... T> bool composite_to(T &...fields) const
154  {
155  if (is_null())
156  {
157  return false;
158  }
159  else
160  {
161  parse_composite(m_home.m_encoding, view(), fields...);
162  return true;
163  }
164  }
165 
167  template<typename T> bool operator>>(T &obj) const { return to(obj); }
168 
170 
180  template<typename T>
181  auto to(T &obj, T const &default_value) const -> typename std::enable_if_t<
182  (not std::is_pointer<T>::value or std::is_same<T, char const *>::value),
183  bool>
184  {
185  bool const null{is_null()};
186  if (null)
187  obj = default_value;
188  else
189  obj = from_string<T>(this->view());
190  return not null;
191  }
192 
194 
197  template<typename T> T as(T const &default_value) const
198  {
199  if (is_null())
200  return default_value;
201  else
202  return from_string<T>(this->view());
203  }
204 
206 
211  template<typename T> T as() const
212  {
213  if (is_null())
214  {
215  if constexpr (not nullness<T>::has_null)
216  {
217  internal::throw_null_conversion(type_name<T>);
218  }
219  else
220  {
221  return nullness<T>::null();
222  }
223  }
224  else
225  {
226  return from_string<T>(this->view());
227  }
228  }
229 
231 
234  template<typename T, template<typename> class O = std::optional>
235  constexpr O<T> get() const
236  {
237  return as<O<T>>();
238  }
239 
241 
248  {
249  return array_parser{c_str(), m_home.m_encoding};
250  }
252 
253 
254 protected:
255  result const &home() const noexcept { return m_home; }
256  result::size_type idx() const noexcept { return m_row; }
257  row_size_type col() const noexcept { return m_col; }
258 
264 
265 private:
266  result m_home;
267  result::size_type m_row;
268 };
269 
270 
271 template<> inline bool field::to<std::string>(std::string &obj) const
272 {
273  bool const null{is_null()};
274  if (not null)
275  obj = std::string{view()};
276  return not null;
277 }
278 
279 
280 template<>
281 inline bool field::to<std::string>(
282  std::string &obj, std::string const &default_value) const
283 {
284  bool const null{is_null()};
285  if (null)
286  obj = default_value;
287  else
288  obj = std::string{view()};
289  return not null;
290 }
291 
292 
294 
299 template<> inline bool field::to<char const *>(char const *&obj) const
300 {
301  bool const null{is_null()};
302  if (not null)
303  obj = c_str();
304  return not null;
305 }
306 
307 
308 template<> inline bool field::to<std::string_view>(std::string_view &obj) const
309 {
310  bool const null{is_null()};
311  if (not null)
312  obj = view();
313  return not null;
314 }
315 
316 
317 template<>
318 inline bool field::to<std::string_view>(
319  std::string_view &obj, std::string_view const &default_value) const
320 {
321  bool const null{is_null()};
322  if (null)
323  obj = default_value;
324  else
325  obj = view();
326  return not null;
327 }
328 
329 
330 template<> inline std::string_view field::as<std::string_view>() const
331 {
332  if (is_null())
333  internal::throw_null_conversion(type_name<std::string_view>);
334  return view();
335 }
336 
337 
338 template<>
339 inline std::string_view
340 field::as<std::string_view>(std::string_view const &default_value) const
341 {
342  return is_null() ? default_value : view();
343 }
344 
345 
346 template<> inline bool field::to<zview>(zview &obj) const
347 {
348  bool const null{is_null()};
349  if (not null)
350  obj = zview{c_str(), size()};
351  return not null;
352 }
353 
354 
355 template<>
356 inline bool field::to<zview>(zview &obj, zview const &default_value) const
357 {
358  bool const null{is_null()};
359  if (null)
360  obj = default_value;
361  else
362  obj = zview{c_str(), size()};
363  return not null;
364 }
365 
366 
367 template<> inline zview field::as<zview>() const
368 {
369  if (is_null())
370  internal::throw_null_conversion(type_name<zview>);
371  return zview{c_str(), size()};
372 }
373 
374 
375 template<> inline zview field::as<zview>(zview const &default_value) const
376 {
377  return is_null() ? default_value : zview{c_str(), size()};
378 }
379 
380 
381 template<typename CHAR = char, typename TRAITS = std::char_traits<CHAR>>
382 class field_streambuf : public std::basic_streambuf<CHAR, TRAITS>
383 {
384 public:
385  using char_type = CHAR;
386  using traits_type = TRAITS;
387  using int_type = typename traits_type::int_type;
388  using pos_type = typename traits_type::pos_type;
389  using off_type = typename traits_type::off_type;
390  using openmode = std::ios::openmode;
391  using seekdir = std::ios::seekdir;
392 
393  explicit field_streambuf(field const &f) : m_field{f} { initialize(); }
394 
395 protected:
396  virtual int sync() override { return traits_type::eof(); }
397 
399  {
400  return traits_type::eof();
401  }
402  virtual pos_type seekpos(pos_type, openmode) override
403  {
404  return traits_type::eof();
405  }
406  virtual int_type overflow(int_type) override { return traits_type::eof(); }
407  virtual int_type underflow() override { return traits_type::eof(); }
408 
409 private:
410  field const &m_field;
411 
412  int_type initialize()
413  {
414  auto g{static_cast<char_type *>(const_cast<char *>(m_field.c_str()))};
415  this->setg(g, g, g + std::size(m_field));
416  return int_type(std::size(m_field));
417  }
418 };
419 
420 
422 
430 template<typename CHAR = char, typename TRAITS = std::char_traits<CHAR>>
431 class basic_fieldstream : public std::basic_istream<CHAR, TRAITS>
432 {
433  using super = std::basic_istream<CHAR, TRAITS>;
434 
435 public:
436  using char_type = CHAR;
437  using traits_type = TRAITS;
438  using int_type = typename traits_type::int_type;
439  using pos_type = typename traits_type::pos_type;
440  using off_type = typename traits_type::off_type;
441 
442  basic_fieldstream(field const &f) : super{nullptr}, m_buf{f}
443  {
444  super::init(&m_buf);
445  }
446 
447 private:
449 };
450 
452 
454 
474 template<typename CHAR>
475 inline std::basic_ostream<CHAR> &
476 operator<<(std::basic_ostream<CHAR> &s, field const &value)
477 {
478  s.write(value.c_str(), std::streamsize(std::size(value)));
479  return s;
480 }
481 
482 
484 
487 template<typename T> inline T from_string(field const &value)
488 {
489  if (value.is_null())
490  {
491  if constexpr (nullness<T>::has_null)
492  return nullness<T>::null();
493  else
494  internal::throw_null_conversion(type_name<T>);
495  }
496  else
497  {
498  return from_string<T>(value.view());
499  }
500 }
501 
502 
504 
510 template<>
511 inline std::nullptr_t from_string<std::nullptr_t>(field const &value)
512 {
513  if (not value.is_null())
514  throw conversion_error{
515  "Extracting non-null field into nullptr_t variable."};
516  return nullptr;
517 }
518 
519 
521 template<> PQXX_LIBEXPORT std::string to_string(field const &value);
522 } // namespace pqxx
523 
524 #include "pqxx/internal/compiler-internal-post.hxx"
525 #endif
typename traits_type::off_type off_type
Definition: field.hxx:389
Input stream that gets its data from a result field.
Definition: field.hxx:431
T as(T const &default_value) const
Return value as object of given type, or default value if null.
Definition: field.hxx:197
void parse_composite(pqxx::internal::encoding_group enc, std::string_view text, T &...fields)
Parse a string representation of a value of a composite type.
Definition: composite.hxx:33
row_size_type m_col
Definition: field.hxx:263
CHAR char_type
Definition: field.hxx:385
field_streambuf(field const &f)
Definition: field.hxx:393
bool operator>>(T &obj) const
Read value into obj; or leave obj untouched and return false if null.
Definition: field.hxx:167
virtual int_type underflow() override
Definition: field.hxx:407
virtual pos_type seekpos(pos_type, openmode) override
Definition: field.hxx:402
PQXX_PURE bool is_null() const noexcept
Is this field&#39;s value null?
Definition: field.cxx:66
bool composite_to(T &...fields) const
Read field as a composite value, write its components into fields.
Definition: field.hxx:153
std::ios::seekdir seekdir
Definition: field.hxx:391
auto to(T &obj) const -> typename std::enable_if_t<(not std::is_pointer< T >::value or std::is_same< T, char const *>::value), bool >
Read value into obj; or if null, leave obj untouched and return false.
Definition: field.hxx:131
field_size_type size_type
Definition: field.hxx:36
TRAITS traits_type
Definition: field.hxx:386
virtual pos_type seekoff(off_type, seekdir, openmode) override
Definition: field.hxx:398
T from_string(field const &value)
Convert a field&#39;s value to type T.
Definition: field.hxx:487
PQXX_PURE row_size_type num() const
Definition: field.hxx:92
result const & home() const noexcept
Definition: field.hxx:255
typename traits_type::int_type int_type
Definition: field.hxx:438
Value conversion failed, e.g. when converting "Hello" to int.
Definition: except.hxx:178
typename traits_type::pos_type pos_type
Definition: field.hxx:388
PQXX_PURE char const * c_str() const
Read as plain C string.
Definition: field.cxx:60
typename traits_type::int_type int_type
Definition: field.hxx:387
typename traits_type::pos_type pos_type
Definition: field.hxx:439
std::string to_string(field const &value)
Convert a field to a string.
Definition: result.cxx:499
row_size_type col() const noexcept
Definition: field.hxx:257
Traits describing a type&#39;s "null value," if any.
Definition: strconv.hxx:86
Reference to one row in a result.
Definition: row.hxx:45
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
T as() const
Return value as object of given type, or throw exception if null.
Definition: field.hxx:211
basic_fieldstream(field const &f)
Definition: field.hxx:442
std::size_t field_size_type
Number of bytes in a field of database data.
Definition: types.hxx:30
int row_size_type
Number of fields in a row of database data.
Definition: types.hxx:24
bool is_null(TYPE const &value) noexcept
Is value null?
Definition: strconv.hxx:331
PQXX_PURE bool operator!=(field const &rhs) const
Byte-by-byte comparison (all nulls are considered equal)
Definition: field.hxx:73
Definition: field.hxx:382
PQXX_PURE std::string_view view() const
Read as string_view, or an empty one if null.
Definition: field.hxx:103
result_size_type size_type
Definition: result.hxx:73
typename traits_type::off_type off_type
Definition: field.hxx:440
CHAR char_type
Definition: field.hxx:436
virtual int sync() override
Definition: field.hxx:396
TRAITS traits_type
Definition: field.hxx:437
static TYPE null()
Return a null value.
void throw_null_conversion(std::string const &type)
Definition: strconv.cxx:242
auto to(T &obj, T const &default_value) const -> typename std::enable_if_t<(not std::is_pointer< T >::value or std::is_same< T, char const *>::value), bool >
Read value into obj; or if null, use default value and return false.
Definition: field.hxx:181
Marker-type wrapper: zero-terminated std::string_view.
Definition: zview.hxx:37
std::ios::openmode openmode
Definition: field.hxx:390
array_parser as_array() const
Parse the field as an SQL array.
Definition: field.hxx:247
result::size_type idx() const noexcept
Definition: field.hxx:256
Reference to a field in a result set.
Definition: field.hxx:33
Result set containing data returned by a query or command.
Definition: result.hxx:70
Low-level array parser.
Definition: array.hxx:46
virtual int_type overflow(int_type) override
Definition: field.hxx:406