libpqxx  7.2.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 
114  [[nodiscard]] PQXX_PURE char const *c_str() const;
115 
117  [[nodiscard]] PQXX_PURE bool is_null() const noexcept;
118 
120  [[nodiscard]] PQXX_PURE size_type size() const noexcept;
121 
123 
126  template<typename T>
127  auto to(T &obj) const -> typename std::enable_if_t<
128  (not std::is_pointer<T>::value or std::is_same<T, char const *>::value),
129  bool>
130  {
131  auto const bytes{c_str()};
132  if (is_null())
133  return false;
134  from_string(bytes, obj);
135  return true;
136  }
137 
139 
144  template<typename... T> bool composite_to(T &... fields) const
145  {
146  if (is_null())
147  {
148  return false;
149  }
150  else
151  {
152  parse_composite(m_home.m_encoding, view(), fields...);
153  return true;
154  }
155  }
156 
158  template<typename T> bool operator>>(T &obj) const { return to(obj); }
159 
161 
164  template<typename T>
165  auto to(T &obj, T const &default_value) const -> typename std::enable_if_t<
166  (not std::is_pointer<T>::value or std::is_same<T, char const *>::value),
167  bool>
168  {
169  bool const has_value{to(obj)};
170  if (not has_value)
171  obj = default_value;
172  return has_value;
173  }
174 
176 
179  template<typename T> T as(T const &default_value) const
180  {
181  T obj;
182  to(obj, default_value);
183  return obj;
184  }
185 
187 
192  template<typename T> T as() const
193  {
194  T obj;
195  if (not to(obj))
196  {
197  if constexpr (nullness<T>::has_null)
198  obj = nullness<T>::null();
199  else
200  internal::throw_null_conversion(type_name<T>);
201  }
202  return obj;
203  }
204 
206 
209  template<typename T, template<typename> class O = std::optional>
210  constexpr O<T> get() const
211  {
212  return as<O<T>>();
213  }
214 
216 
223  {
224  return array_parser{c_str(), m_home.m_encoding};
225  }
227 
228 
229 protected:
230  result const &home() const noexcept { return m_home; }
231  result::size_type idx() const noexcept { return m_row; }
232  row_size_type col() const noexcept { return m_col; }
233 
239 
240 private:
241  result m_home;
242  result::size_type m_row;
243 };
244 
245 
247 template<> inline bool field::to<std::string>(std::string &obj) const
248 {
249  char const *const bytes = c_str();
250  if (bytes[0] == '\0' and is_null())
251  return false;
252  obj = std::string{bytes, size()};
253  return true;
254 }
255 
257 
262 template<> inline bool field::to<char const *>(char const *&obj) const
263 {
264  if (is_null())
265  return false;
266  obj = c_str();
267  return true;
268 }
269 
270 
271 template<typename CHAR = char, typename TRAITS = std::char_traits<CHAR>>
272 class field_streambuf : public std::basic_streambuf<CHAR, TRAITS>
273 {
274 public:
275  using char_type = CHAR;
276  using traits_type = TRAITS;
277  using int_type = typename traits_type::int_type;
278  using pos_type = typename traits_type::pos_type;
279  using off_type = typename traits_type::off_type;
280  using openmode = std::ios::openmode;
281  using seekdir = std::ios::seekdir;
282 
283  explicit field_streambuf(field const &f) : m_field{f} { initialize(); }
284 
285 protected:
286  virtual int sync() override { return traits_type::eof(); }
287 
289  {
290  return traits_type::eof();
291  }
292  virtual pos_type seekpos(pos_type, openmode) override
293  {
294  return traits_type::eof();
295  }
296  virtual int_type overflow(int_type) override { return traits_type::eof(); }
297  virtual int_type underflow() override { return traits_type::eof(); }
298 
299 private:
300  field const &m_field;
301 
302  int_type initialize()
303  {
304  auto g{static_cast<char_type *>(const_cast<char *>(m_field.c_str()))};
305  this->setg(g, g, g + std::size(m_field));
306  return int_type(std::size(m_field));
307  }
308 };
309 
310 
312 
320 template<typename CHAR = char, typename TRAITS = std::char_traits<CHAR>>
321 class basic_fieldstream : public std::basic_istream<CHAR, TRAITS>
322 {
323  using super = std::basic_istream<CHAR, TRAITS>;
324 
325 public:
326  using char_type = CHAR;
327  using traits_type = TRAITS;
328  using int_type = typename traits_type::int_type;
329  using pos_type = typename traits_type::pos_type;
330  using off_type = typename traits_type::off_type;
331 
332  basic_fieldstream(field const &f) : super{nullptr}, m_buf{f}
333  {
334  super::init(&m_buf);
335  }
336 
337 private:
339 };
340 
342 
344 
364 template<typename CHAR>
365 inline std::basic_ostream<CHAR> &
366 operator<<(std::basic_ostream<CHAR> &s, field const &value)
367 {
368  s.write(value.c_str(), std::streamsize(std::size(value)));
369  return s;
370 }
371 
372 
374 
377 template<typename T> inline T from_string(field const &value)
378 {
379  if (value.is_null())
380  {
381  if constexpr (nullness<T>::has_null)
382  return nullness<T>::null();
383  else
384  internal::throw_null_conversion(type_name<T>);
385  }
386  else
387  {
388  return from_string<T>(value.view());
389  }
390 }
391 
392 
394 
400 template<>
401 inline std::nullptr_t from_string<std::nullptr_t>(field const &value)
402 {
403  if (not value.is_null())
404  throw conversion_error{
405  "Extracting non-null field into nullptr_t variable."};
406  return nullptr;
407 }
408 
409 
411 template<> PQXX_LIBEXPORT std::string to_string(field const &value);
412 } // namespace pqxx
413 
414 #include "pqxx/internal/compiler-internal-post.hxx"
415 #endif
array_parser as_array() const
Parse the field as an SQL array.
Definition: field.hxx:222
result::size_type idx() const noexcept
Definition: field.hxx:231
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:127
typename traits_type::int_type int_type
Definition: field.hxx:328
result const & home() const noexcept
Definition: field.hxx:230
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:277
Definition: field.hxx:272
row_size_type m_col
Definition: field.hxx:238
T from_string(field const &value)
Convert a field&#39;s value to type T.
Definition: field.hxx:377
bool operator>>(T &obj) const
Read value into obj; or leave obj untouched and return false if null.
Definition: field.hxx:158
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:144
std::ios::seekdir seekdir
Definition: field.hxx:281
std::string to_string(field const &value)
Convert a field to a string.
Definition: result.cxx:498
std::ios::openmode openmode
Definition: field.hxx:280
TRAITS traits_type
Definition: field.hxx:327
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
field_size_type size_type
Definition: field.hxx:36
virtual pos_type seekoff(off_type, seekdir, openmode) override
Definition: field.hxx:288
PQXX_PURE row_size_type num() const
Definition: field.hxx:92
Reference to one row in a result.
Definition: row.hxx:43
result_size_type size_type
Definition: result.hxx:73
virtual int_type overflow(int_type) override
Definition: field.hxx:296
Reference to a field in a result set.
Definition: field.hxx:33
virtual int sync() override
Definition: field.hxx:286
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
field_streambuf(field const &f)
Definition: field.hxx:283
bool is_null(TYPE const &value) noexcept
Is value null?
Definition: strconv.hxx:310
row_size_type col() const noexcept
Definition: field.hxx:232
Input stream that gets its data from a result field.
Definition: field.hxx:321
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:30
typename traits_type::pos_type pos_type
Definition: field.hxx:329
Result set containing data returned by a query or command.
Definition: result.hxx:70
basic_fieldstream(field const &f)
Definition: field.hxx:332
T as() const
Return value as object of given type, or throw exception if null.
Definition: field.hxx:192
virtual pos_type seekpos(pos_type, openmode) override
Definition: field.hxx:292
typename traits_type::pos_type pos_type
Definition: field.hxx:278
static TYPE null()
Return a null value.
void throw_null_conversion(std::string const &type)
Definition: strconv.cxx:243
PQXX_PURE bool operator!=(field const &rhs) const
Byte-by-byte comparison (all nulls are considered equal)
Definition: field.hxx:73
PQXX_PURE std::string_view view() const
Read as string_view.
Definition: field.hxx:103
TRAITS traits_type
Definition: field.hxx:276
typename traits_type::off_type off_type
Definition: field.hxx:279
T as(T const &default_value) const
Return value as object of given type, or default value if null.
Definition: field.hxx:179
CHAR char_type
Definition: field.hxx:326
Value conversion failed, e.g. when converting "Hello" to int.
Definition: except.hxx:178
CHAR char_type
Definition: field.hxx:275
typename traits_type::off_type off_type
Definition: field.hxx:330
Low-level array parser.
Definition: array.hxx:46
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:165
Traits describing a type&#39;s "null value," if any.
Definition: strconv.hxx:86
virtual int_type underflow() override
Definition: field.hxx:297