libpqxx  7.5.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-2021, 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  PQXX_DEPRECATED("Do not construct fields yourself. Get them from the row.")
44  field(row const &r, row_size_type c) noexcept;
45 
47  PQXX_DEPRECATED("Do not construct fields yourself. Get them from the row.")
48  field() = default;
49 
54 
71  [[nodiscard]] PQXX_PURE bool operator==(field const &) const;
72 
74 
76  [[nodiscard]] PQXX_PURE bool operator!=(field const &rhs) const
77  {
78  return not operator==(rhs);
79  }
81 
86  [[nodiscard]] PQXX_PURE char const *name() const;
88 
90  [[nodiscard]] oid PQXX_PURE type() const;
91 
93  [[nodiscard]] PQXX_PURE oid table() const;
94 
96  PQXX_PURE row_size_type num() const { return col(); }
97 
99  [[nodiscard]] PQXX_PURE row_size_type table_column() const;
101 
106  [[nodiscard]] PQXX_PURE std::string_view view() const
108  {
109  return std::string_view(c_str(), size());
110  }
111 
113 
122  [[nodiscard]] PQXX_PURE char const *c_str() const;
123 
125  [[nodiscard]] PQXX_PURE bool is_null() const noexcept;
126 
128  [[nodiscard]] PQXX_PURE size_type size() const noexcept;
129 
131 
134  template<typename T>
135  auto to(T &obj) const -> typename std::enable_if_t<
136  (not std::is_pointer<T>::value or std::is_same<T, char const *>::value),
137  bool>
138  {
139  if (is_null())
140  {
141  return false;
142  }
143  else
144  {
145  auto const bytes{c_str()};
146  from_string(bytes, obj);
147  return true;
148  }
149  }
150 
152 
157  template<typename... T> bool composite_to(T &...fields) const
158  {
159  if (is_null())
160  {
161  return false;
162  }
163  else
164  {
165  parse_composite(m_home.m_encoding, view(), fields...);
166  return true;
167  }
168  }
169 
171  template<typename T> bool operator>>(T &obj) const { return to(obj); }
172 
174 
184  template<typename T>
185  auto to(T &obj, T const &default_value) const -> typename std::enable_if_t<
186  (not std::is_pointer<T>::value or std::is_same<T, char const *>::value),
187  bool>
188  {
189  bool const null{is_null()};
190  if (null)
191  obj = default_value;
192  else
193  obj = from_string<T>(this->view());
194  return not null;
195  }
196 
198 
201  template<typename T> T as(T const &default_value) const
202  {
203  if (is_null())
204  return default_value;
205  else
206  return from_string<T>(this->view());
207  }
208 
210 
215  template<typename T> T as() const
216  {
217  if (is_null())
218  {
219  if constexpr (not nullness<T>::has_null)
220  {
221  internal::throw_null_conversion(type_name<T>);
222  }
223  else
224  {
225  return nullness<T>::null();
226  }
227  }
228  else
229  {
230  return from_string<T>(this->view());
231  }
232  }
233 
235 
238  template<typename T, template<typename> class O = std::optional>
239  constexpr O<T> get() const
240  {
241  return as<O<T>>();
242  }
243 
245 
252  {
253  return array_parser{c_str(), m_home.m_encoding};
254  }
256 
257 
258 protected:
259  result const &home() const noexcept { return m_home; }
260  result::size_type idx() const noexcept { return m_row; }
261  row_size_type col() const noexcept { return m_col; }
262 
268 
269 private:
270  result m_home;
271  result::size_type m_row;
272 };
273 
274 
275 template<> inline bool field::to<std::string>(std::string &obj) const
276 {
277  bool const null{is_null()};
278  if (not null)
279  obj = std::string{view()};
280  return not null;
281 }
282 
283 
284 template<>
285 inline bool field::to<std::string>(
286  std::string &obj, std::string const &default_value) const
287 {
288  bool const null{is_null()};
289  if (null)
290  obj = default_value;
291  else
292  obj = std::string{view()};
293  return not null;
294 }
295 
296 
298 
303 template<> inline bool field::to<char const *>(char const *&obj) const
304 {
305  bool const null{is_null()};
306  if (not null)
307  obj = c_str();
308  return not null;
309 }
310 
311 
312 template<> inline bool field::to<std::string_view>(std::string_view &obj) const
313 {
314  bool const null{is_null()};
315  if (not null)
316  obj = view();
317  return not null;
318 }
319 
320 
321 template<>
322 inline bool field::to<std::string_view>(
323  std::string_view &obj, std::string_view const &default_value) const
324 {
325  bool const null{is_null()};
326  if (null)
327  obj = default_value;
328  else
329  obj = view();
330  return not null;
331 }
332 
333 
334 template<> inline std::string_view field::as<std::string_view>() const
335 {
336  if (is_null())
337  internal::throw_null_conversion(type_name<std::string_view>);
338  return view();
339 }
340 
341 
342 template<>
343 inline std::string_view
344 field::as<std::string_view>(std::string_view const &default_value) const
345 {
346  return is_null() ? default_value : view();
347 }
348 
349 
350 template<> inline bool field::to<zview>(zview &obj) const
351 {
352  bool const null{is_null()};
353  if (not null)
354  obj = zview{c_str(), size()};
355  return not null;
356 }
357 
358 
359 template<>
360 inline bool field::to<zview>(zview &obj, zview const &default_value) const
361 {
362  bool const null{is_null()};
363  if (null)
364  obj = default_value;
365  else
366  obj = zview{c_str(), size()};
367  return not null;
368 }
369 
370 
371 template<> inline zview field::as<zview>() const
372 {
373  if (is_null())
374  internal::throw_null_conversion(type_name<zview>);
375  return zview{c_str(), size()};
376 }
377 
378 
379 template<> inline zview field::as<zview>(zview const &default_value) const
380 {
381  return is_null() ? default_value : zview{c_str(), size()};
382 }
383 
384 
385 template<typename CHAR = char, typename TRAITS = std::char_traits<CHAR>>
386 class field_streambuf : public std::basic_streambuf<CHAR, TRAITS>
387 {
388 public:
389  using char_type = CHAR;
390  using traits_type = TRAITS;
391  using int_type = typename traits_type::int_type;
392  using pos_type = typename traits_type::pos_type;
393  using off_type = typename traits_type::off_type;
394  using openmode = std::ios::openmode;
395  using seekdir = std::ios::seekdir;
396 
397  explicit field_streambuf(field const &f) : m_field{f} { initialize(); }
398 
399 protected:
400  virtual int sync() override { return traits_type::eof(); }
401 
403  {
404  return traits_type::eof();
405  }
406  virtual pos_type seekpos(pos_type, openmode) override
407  {
408  return traits_type::eof();
409  }
410  virtual int_type overflow(int_type) override { return traits_type::eof(); }
411  virtual int_type underflow() override { return traits_type::eof(); }
412 
413 private:
414  field const &m_field;
415 
416  int_type initialize()
417  {
418  auto g{static_cast<char_type *>(const_cast<char *>(m_field.c_str()))};
419  this->setg(g, g, g + std::size(m_field));
420  return int_type(std::size(m_field));
421  }
422 };
423 
424 
426 
434 template<typename CHAR = char, typename TRAITS = std::char_traits<CHAR>>
435 class basic_fieldstream : public std::basic_istream<CHAR, TRAITS>
436 {
437  using super = std::basic_istream<CHAR, TRAITS>;
438 
439 public:
440  using char_type = CHAR;
441  using traits_type = TRAITS;
442  using int_type = typename traits_type::int_type;
443  using pos_type = typename traits_type::pos_type;
444  using off_type = typename traits_type::off_type;
445 
446  basic_fieldstream(field const &f) : super{nullptr}, m_buf{f}
447  {
448  super::init(&m_buf);
449  }
450 
451 private:
453 };
454 
456 
458 
478 template<typename CHAR>
479 inline std::basic_ostream<CHAR> &
480 operator<<(std::basic_ostream<CHAR> &s, field const &value)
481 {
482  s.write(value.c_str(), std::streamsize(std::size(value)));
483  return s;
484 }
485 
486 
488 
491 template<typename T> inline T from_string(field const &value)
492 {
493  if (value.is_null())
494  {
495  if constexpr (nullness<T>::has_null)
496  return nullness<T>::null();
497  else
498  internal::throw_null_conversion(type_name<T>);
499  }
500  else
501  {
502  return from_string<T>(value.view());
503  }
504 }
505 
506 
508 
514 template<>
515 inline std::nullptr_t from_string<std::nullptr_t>(field const &value)
516 {
517  if (not value.is_null())
518  throw conversion_error{
519  "Extracting non-null field into nullptr_t variable."};
520  return nullptr;
521 }
522 
523 
525 template<> PQXX_LIBEXPORT std::string to_string(field const &value);
526 } // namespace pqxx
527 
528 #include "pqxx/internal/compiler-internal-post.hxx"
529 #endif
basic_fieldstream(field const &f)
Definition: field.hxx:446
std::ios::seekdir seekdir
Definition: field.hxx:395
Definition: field.hxx:386
PQXX_PURE std::string_view view() const
Read as string_view, or an empty one if null.
Definition: field.hxx:107
std::string to_string(field const &value)
Convert a field to a string.
Definition: result.cxx:503
typename traits_type::int_type int_type
Definition: field.hxx:391
row_size_type m_col
Definition: field.hxx:267
std::size_t field_size_type
Number of bytes in a field of database data.
Definition: types.hxx:30
PQXX_PURE char const * c_str() const
Read as plain C string.
Definition: field.cxx:60
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
result::size_type idx() const noexcept
Definition: field.hxx:260
Result set containing data returned by a query or command.
Definition: result.hxx:70
PQXX_PURE bool is_null() const noexcept
Is this field&#39;s value null?
Definition: field.cxx:66
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
row_size_type col() const noexcept
Definition: field.hxx:261
T as(T const &default_value) const
Return value as object of given type, or default value if null.
Definition: field.hxx:201
array_parser as_array() const
Parse the field as an SQL array.
Definition: field.hxx:251
typename traits_type::int_type int_type
Definition: field.hxx:442
bool is_null(TYPE const &value) noexcept
Is value null?
Definition: strconv.hxx:353
std::ios::openmode openmode
Definition: field.hxx:394
TRAITS traits_type
Definition: field.hxx:441
T as() const
Return value as object of given type, or throw exception if null.
Definition: field.hxx:215
bool operator>>(T &obj) const
Read value into obj; or leave obj untouched and return false if null.
Definition: field.hxx:171
virtual int sync() override
Definition: field.hxx:400
virtual pos_type seekoff(off_type, seekdir, openmode) override
Definition: field.hxx:402
virtual int_type overflow(int_type) override
Definition: field.hxx:410
field_streambuf(field const &f)
Definition: field.hxx:397
typename traits_type::pos_type pos_type
Definition: field.hxx:392
Traits describing a type&#39;s "null value," if any.
Definition: strconv.hxx:86
field_size_type size_type
Definition: field.hxx:36
T from_string(field const &value)
Convert a field&#39;s value to type T.
Definition: field.hxx:491
PQXX_PURE row_size_type num() const
Return row number. The first row is row 0, the second is row 1, etc.
Definition: field.hxx:96
Reference to one row in a result.
Definition: row.hxx:45
virtual pos_type seekpos(pos_type, openmode) override
Definition: field.hxx:406
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:135
typename traits_type::off_type off_type
Definition: field.hxx:393
static TYPE null()
Return a null value.
typename traits_type::pos_type pos_type
Definition: field.hxx:443
Reference to a field in a result set.
Definition: field.hxx:33
result_size_type size_type
Definition: result.hxx:73
Low-level array parser.
Definition: array.hxx:46
typename traits_type::off_type off_type
Definition: field.hxx:444
result const & home() const noexcept
Definition: field.hxx:259
int row_size_type
Number of fields in a row of database data.
Definition: types.hxx:24
virtual int_type underflow() override
Definition: field.hxx:411
Marker-type wrapper: zero-terminated std::string_view.
Definition: zview.hxx:37
void throw_null_conversion(std::string const &type)
Definition: strconv.cxx:242
TRAITS traits_type
Definition: field.hxx:390
Value conversion failed, e.g. when converting "Hello" to int.
Definition: except.hxx:178
CHAR char_type
Definition: field.hxx:440
CHAR char_type
Definition: field.hxx:389
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:185
Input stream that gets its data from a result field.
Definition: field.hxx:435
bool composite_to(T &...fields) const
Read field as a composite value, write its components into fields.
Definition: field.hxx:157