libpqxx  7.0.6
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/result.hxx"
23 #include "pqxx/strconv.hxx"
24 #include "pqxx/types.hxx"
25 
26 namespace pqxx
27 {
29 
32 class PQXX_LIBEXPORT field
33 {
34 public:
36 
38 
42  field(row const &r, row_size_type c) noexcept;
43 
44  field() = default;
45 
50 
67  [[nodiscard]] bool operator==(field const &) const;
68 
70 
72  [[nodiscard]] bool operator!=(field const &rhs) const
73  {
74  return not operator==(rhs);
75  }
77 
82  [[nodiscard]] char const *name() const;
84 
86  [[nodiscard]] oid type() const;
87 
89  [[nodiscard]] oid table() const;
90 
91  row_size_type num() const { return col(); }
92 
94  [[nodiscard]] row_size_type table_column() const;
96 
101  [[nodiscard]] std::string_view view() const
103  {
104  return std::string_view(c_str(), size());
105  }
106 
108 
113  [[nodiscard]] char const *c_str() const;
114 
116  [[nodiscard]] bool is_null() const noexcept;
117 
119 
122  [[nodiscard]] size_type size() const noexcept;
123 
125 
128  template<typename T>
129  auto to(T &obj) const -> typename std::enable_if<
130  (not std::is_pointer<T>::value or std::is_same<T, char const *>::value),
131  bool>::type
132  {
133  auto const bytes{c_str()};
134  if (bytes[0] == '\0' and is_null())
135  return false;
136  from_string(bytes, obj);
137  return true;
138  }
139 
141  template<typename T> bool operator>>(T &obj) const { return to(obj); }
142 
144 
147  template<typename T>
148  auto to(T &obj, T const &default_value) const -> typename std::enable_if<
149  (not std::is_pointer<T>::value or std::is_same<T, char const *>::value),
150  bool>::type
151  {
152  bool const has_value{to(obj)};
153  if (not has_value)
154  obj = default_value;
155  return has_value;
156  }
157 
159 
162  template<typename T> T as(T const &default_value) const
163  {
164  T obj;
165  to(obj, default_value);
166  return obj;
167  }
168 
170 
175  template<typename T> T as() const
176  {
177  T obj;
178  if (not to(obj))
179  {
180  if constexpr (nullness<T>::has_null)
181  obj = nullness<T>::null();
182  else
183  internal::throw_null_conversion(type_name<T>);
184  }
185  return obj;
186  }
187 
189 
192  template<typename T, template<typename> class O = std::optional>
193  constexpr O<T> get() const
194  {
195  return as<O<T>>();
196  }
197 
199 
206  {
207  return array_parser{c_str(), m_home.m_encoding};
208  }
210 
211 
212 protected:
213  result const &home() const noexcept { return m_home; }
214  result::size_type idx() const noexcept { return m_row; }
215  row_size_type col() const noexcept { return m_col; }
216 
222 
223 private:
224  result m_home;
225  result::size_type m_row;
226 };
227 
228 
230 template<> inline bool field::to<std::string>(std::string &obj) const
231 {
232  char const *const bytes = c_str();
233  if (bytes[0] == '\0' and is_null())
234  return false;
235  obj = std::string{bytes, size()};
236  return true;
237 }
238 
240 
245 template<> inline bool field::to<char const *>(char const *&obj) const
246 {
247  if (is_null())
248  return false;
249  obj = c_str();
250  return true;
251 }
252 
253 
254 template<typename CHAR = char, typename TRAITS = std::char_traits<CHAR>>
255 class field_streambuf : public std::basic_streambuf<CHAR, TRAITS>
256 {
257 public:
258  using char_type = CHAR;
259  using traits_type = TRAITS;
260  using int_type = typename traits_type::int_type;
261  using pos_type = typename traits_type::pos_type;
262  using off_type = typename traits_type::off_type;
263  using openmode = std::ios::openmode;
264  using seekdir = std::ios::seekdir;
265 
266  explicit field_streambuf(field const &f) : m_field{f} { initialize(); }
267 
268 protected:
269  virtual int sync() override { return traits_type::eof(); }
270 
272  {
273  return traits_type::eof();
274  }
275  virtual pos_type seekpos(pos_type, openmode) override
276  {
277  return traits_type::eof();
278  }
279  virtual int_type overflow(int_type) override { return traits_type::eof(); }
280  virtual int_type underflow() override { return traits_type::eof(); }
281 
282 private:
283  field const &m_field;
284 
285  int_type initialize()
286  {
287  auto g{static_cast<char_type *>(const_cast<char *>(m_field.c_str()))};
288  this->setg(g, g, g + m_field.size());
289  return int_type(m_field.size());
290  }
291 };
292 
293 
295 
303 template<typename CHAR = char, typename TRAITS = std::char_traits<CHAR>>
304 class basic_fieldstream : public std::basic_istream<CHAR, TRAITS>
305 {
306  using super = std::basic_istream<CHAR, TRAITS>;
307 
308 public:
309  using char_type = CHAR;
310  using traits_type = TRAITS;
311  using int_type = typename traits_type::int_type;
312  using pos_type = typename traits_type::pos_type;
313  using off_type = typename traits_type::off_type;
314 
315  basic_fieldstream(field const &f) : super{nullptr}, m_buf{f}
316  {
317  super::init(&m_buf);
318  }
319 
320 private:
322 };
323 
325 
327 
347 template<typename CHAR>
348 inline std::basic_ostream<CHAR> &
349 operator<<(std::basic_ostream<CHAR> &s, field const &value)
350 {
351  s.write(value.c_str(), std::streamsize(value.size()));
352  return s;
353 }
354 
355 
357 template<typename T> inline T from_string(field const &value)
358 {
359  return from_string<T>(value.view());
360 }
361 
363 template<> PQXX_LIBEXPORT std::string to_string(field const &value);
364 } // namespace pqxx
365 
366 #include "pqxx/internal/compiler-internal-post.hxx"
367 #endif
typename traits_type::pos_type pos_type
Definition: field.hxx:312
TRAITS traits_type
Definition: field.hxx:310
auto to(T &obj, T const &default_value) const -> typename std::enable_if<(not std::is_pointer< T >::value or std::is_same< T, char const *>::value), bool >::type
Read value into obj; or if null, use default value and return false.
Definition: field.hxx:148
row_size_type col() const noexcept
Definition: field.hxx:215
bool is_null(TYPE const &value)
Is value null?
Definition: strconv.hxx:286
row_size_type m_col
Definition: field.hxx:221
virtual pos_type seekoff(off_type, seekdir, openmode) override
Definition: field.hxx:271
field_streambuf(field const &f)
Definition: field.hxx:266
Low-level array parser.
Definition: array.hxx:46
virtual int_type underflow() override
Definition: field.hxx:280
virtual pos_type seekpos(pos_type, openmode) override
Definition: field.hxx:275
CHAR char_type
Definition: field.hxx:309
std::ios::openmode openmode
Definition: field.hxx:263
typename traits_type::off_type off_type
Definition: field.hxx:262
virtual int_type overflow(int_type) override
Definition: field.hxx:279
T from_string(field const &value)
Convert a field&#39;s string contents to another type.
Definition: field.hxx:357
Definition: field.hxx:255
CHAR char_type
Definition: field.hxx:258
result const & home() const noexcept
Definition: field.hxx:213
std::string to_string(field const &value)
Convert a field to a string.
Definition: result.cxx:478
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
size_t field_size_type
Number of bytes in a field of database data.
Definition: types.hxx:30
std::string_view view() const
Read as string_view.
Definition: field.hxx:102
int row_size_type
Number of fields in a row of database data.
Definition: types.hxx:24
TRAITS traits_type
Definition: field.hxx:259
char const * c_str() const
Read as plain C string.
Definition: field.cxx:62
result::size_type idx() const noexcept
Definition: field.hxx:214
T as(T const &default_value) const
Return value as object of given type, or default value if null.
Definition: field.hxx:162
Traits describing a type&#39;s "null value," if any.
Definition: strconv.hxx:86
T as() const
Return value as object of given type, or throw exception if null.
Definition: field.hxx:175
bool operator!=(field const &rhs) const
Byte-by-byte comparison (all nulls are considered equal)
Definition: field.hxx:72
Input stream that gets its data from a result field.
Definition: field.hxx:304
typename traits_type::off_type off_type
Definition: field.hxx:313
Result set containing data returned by a query or command.
Definition: result.hxx:70
size_type size() const noexcept
Return number of bytes taken up by the field&#39;s value.
Definition: field.cxx:74
row_size_type num() const
Definition: field.hxx:91
static TYPE null()
Return a null value.
result_size_type size_type
Definition: result.hxx:73
void throw_null_conversion(std::string const &type)
Definition: strconv.cxx:241
bool operator>>(T &obj) const
Read value into obj; or leave obj untouched and return false if null.
Definition: field.hxx:141
auto to(T &obj) const -> typename std::enable_if<(not std::is_pointer< T >::value or std::is_same< T, char const *>::value), bool >::type
Read value into obj; or if null, leave obj untouched and return false.
Definition: field.hxx:129
field_size_type size_type
Definition: field.hxx:35
typename traits_type::int_type int_type
Definition: field.hxx:260
Reference to one row in a result.
Definition: row.hxx:38
array_parser as_array() const
Parse the field as an SQL array.
Definition: field.hxx:205
std::ios::seekdir seekdir
Definition: field.hxx:264
typename traits_type::pos_type pos_type
Definition: field.hxx:261
virtual int sync() override
Definition: field.hxx:269
basic_fieldstream(field const &f)
Definition: field.hxx:315
Reference to a field in a result set.
Definition: field.hxx:32