libpqxx 7.7.5
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-2023, 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#if !defined(PQXX_HEADER_PRE)
17# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
18#endif
19
20#include <optional>
21
22#include "pqxx/array.hxx"
23#include "pqxx/composite.hxx"
24#include "pqxx/result.hxx"
25#include "pqxx/strconv.hxx"
26#include "pqxx/types.hxx"
27
28namespace pqxx
29{
31
34class PQXX_LIBEXPORT field
35{
36public:
38
40
44 [[deprecated(
45 "Do not construct fields yourself. Get them from the row.")]] field(row const &r, row_size_type c) noexcept;
46
48 [[deprecated(
49 "Do not construct fields yourself. Get them from the "
50 "row.")]] field() noexcept = default;
51
56 // TODO: noexcept. Breaks ABI.
58
74 [[nodiscard]] PQXX_PURE bool operator==(field const &) const;
75
77
79 [[nodiscard]] PQXX_PURE bool operator!=(field const &rhs) const noexcept
80 {
81 return not operator==(rhs);
82 }
84
90 [[nodiscard]] PQXX_PURE char const *name() const &;
91
93 [[nodiscard]] oid PQXX_PURE type() const;
94
96 [[nodiscard]] PQXX_PURE oid table() const;
97
99 PQXX_PURE constexpr row_size_type num() const noexcept { return col(); }
100
102 [[nodiscard]] PQXX_PURE row_size_type table_column() const;
104
110
114 [[nodiscard]] PQXX_PURE std::string_view view() const &
115 {
116 return std::string_view(c_str(), size());
117 }
118
120
129 [[nodiscard]] PQXX_PURE char const *c_str() const &;
130
132 [[nodiscard]] PQXX_PURE bool is_null() const noexcept;
133
135 [[nodiscard]] PQXX_PURE size_type size() const noexcept;
136
138
141 template<typename T>
142 auto to(T &obj) const -> typename std::enable_if_t<
143 (not std::is_pointer<T>::value or std::is_same<T, char const *>::value),
144 bool>
145 {
146 if (is_null())
147 {
148 return false;
149 }
150 else
151 {
152 auto const bytes{c_str()};
153 from_string(bytes, obj);
154 return true;
155 }
156 }
157
159
164 template<typename... T> bool composite_to(T &...fields) const
165 {
166 if (is_null())
167 {
168 return false;
169 }
170 else
171 {
172 parse_composite(m_home.m_encoding, view(), fields...);
173 return true;
174 }
175 }
176
178 template<typename T> bool operator>>(T &obj) const { return to(obj); }
179
181
191 template<typename T>
192 auto to(T &obj, T const &default_value) const -> typename std::enable_if_t<
193 (not std::is_pointer<T>::value or std::is_same<T, char const *>::value),
194 bool>
195 {
196 bool const null{is_null()};
197 if (null)
198 obj = default_value;
199 else
200 obj = from_string<T>(this->view());
201 return not null;
202 }
203
205
208 template<typename T> T as(T const &default_value) const
209 {
210 if (is_null())
211 return default_value;
212 else
213 return from_string<T>(this->view());
214 }
215
217
222 template<typename T> T as() const
223 {
224 if (is_null())
225 {
226 if constexpr (not nullness<T>::has_null)
227 internal::throw_null_conversion(type_name<T>);
228 else
229 return nullness<T>::null();
230 }
231 else
232 {
233 return from_string<T>(this->view());
234 }
235 }
236
238
241 template<typename T, template<typename> class O = std::optional>
242 constexpr O<T> get() const
243 {
244 return as<O<T>>();
245 }
246
247 // TODO: constexpr noexcept, once array_parser constructor gets those.
249
256 {
257 return array_parser{c_str(), m_home.m_encoding};
258 }
260
261
262protected:
263 constexpr result const &home() const noexcept { return m_home; }
264 constexpr result::size_type idx() const noexcept { return m_row; }
265 constexpr row_size_type col() const noexcept { return m_col; }
266
267 // TODO: Create gates.
268 friend class pqxx::result;
269 friend class pqxx::row;
271 result const &r, result_size_type row_num, row_size_type col_num) noexcept
272 :
273 m_col{col_num}, m_home{r}, m_row{row_num}
274 {}
275
281
282private:
283 result m_home;
284 result::size_type m_row;
285};
286
287
288template<> inline bool field::to<std::string>(std::string &obj) const
289{
290 bool const null{is_null()};
291 if (not null)
292 obj = std::string{view()};
293 return not null;
294}
295
296
297template<>
298inline bool field::to<std::string>(
299 std::string &obj, std::string const &default_value) const
300{
301 bool const null{is_null()};
302 if (null)
303 obj = default_value;
304 else
305 obj = std::string{view()};
306 return not null;
307}
308
309
311
316template<> inline bool field::to<char const *>(char const *&obj) const
317{
318 bool const null{is_null()};
319 if (not null)
320 obj = c_str();
321 return not null;
322}
323
324
325template<> inline bool field::to<std::string_view>(std::string_view &obj) const
326{
327 bool const null{is_null()};
328 if (not null)
329 obj = view();
330 return not null;
331}
332
333
334template<>
335inline bool field::to<std::string_view>(
336 std::string_view &obj, std::string_view const &default_value) const
337{
338 bool const null{is_null()};
339 if (null)
340 obj = default_value;
341 else
342 obj = view();
343 return not null;
344}
345
346
347template<> inline std::string_view field::as<std::string_view>() const
348{
349 if (is_null())
350 PQXX_UNLIKELY
351 internal::throw_null_conversion(type_name<std::string_view>);
352 return view();
353}
354
355
356template<>
357inline std::string_view
358field::as<std::string_view>(std::string_view const &default_value) const
359{
360 return is_null() ? default_value : view();
361}
362
363
364template<> inline bool field::to<zview>(zview &obj) const
365{
366 bool const null{is_null()};
367 if (not null)
368 obj = zview{c_str(), size()};
369 return not null;
370}
371
372
373template<>
374inline bool field::to<zview>(zview &obj, zview const &default_value) const
375{
376 bool const null{is_null()};
377 if (null)
378 obj = default_value;
379 else
380 obj = zview{c_str(), size()};
381 return not null;
382}
383
384
385template<> inline zview field::as<zview>() const
386{
387 if (is_null())
388 PQXX_UNLIKELY
389 internal::throw_null_conversion(type_name<zview>);
390 return zview{c_str(), size()};
391}
392
393
394template<> inline zview field::as<zview>(zview const &default_value) const
395{
396 return is_null() ? default_value : zview{c_str(), size()};
397}
398
399
400template<typename CHAR = char, typename TRAITS = std::char_traits<CHAR>>
401class field_streambuf : public std::basic_streambuf<CHAR, TRAITS>
402{
403public:
404 using char_type = CHAR;
405 using traits_type = TRAITS;
406 using int_type = typename traits_type::int_type;
407 using pos_type = typename traits_type::pos_type;
408 using off_type = typename traits_type::off_type;
409 using openmode = std::ios::openmode;
410 using seekdir = std::ios::seekdir;
411
412 explicit field_streambuf(field const &f) : m_field{f} { initialize(); }
413
414protected:
415 virtual int sync() override { return traits_type::eof(); }
416
418 {
419 return traits_type::eof();
420 }
422 {
423 return traits_type::eof();
424 }
425 virtual int_type overflow(int_type) override { return traits_type::eof(); }
426 virtual int_type underflow() override { return traits_type::eof(); }
427
428private:
429 field const &m_field;
430
431 int_type initialize()
432 {
433 auto g{static_cast<char_type *>(const_cast<char *>(m_field.c_str()))};
434 this->setg(g, g, g + std::size(m_field));
435 return int_type(std::size(m_field));
436 }
437};
438
439
441
449template<typename CHAR = char, typename TRAITS = std::char_traits<CHAR>>
450class basic_fieldstream : public std::basic_istream<CHAR, TRAITS>
451{
452 using super = std::basic_istream<CHAR, TRAITS>;
453
454public:
455 using char_type = CHAR;
456 using traits_type = TRAITS;
457 using int_type = typename traits_type::int_type;
458 using pos_type = typename traits_type::pos_type;
459 using off_type = typename traits_type::off_type;
460
461 basic_fieldstream(field const &f) : super{nullptr}, m_buf{f}
462 {
463 super::init(&m_buf);
464 }
465
466private:
468};
469
471
473
493template<typename CHAR>
494inline std::basic_ostream<CHAR> &
495operator<<(std::basic_ostream<CHAR> &s, field const &value)
496{
497 s.write(value.c_str(), std::streamsize(std::size(value)));
498 return s;
499}
500
501
503
506template<typename T> inline T from_string(field const &value)
507{
508 if (value.is_null())
509 {
510 if constexpr (nullness<T>::has_null)
511 return nullness<T>::null();
512 else
514 }
515 else
516 {
517 return from_string<T>(value.view());
518 }
519}
520
521
523
529template<>
530inline std::nullptr_t from_string<std::nullptr_t>(field const &value)
531{
532 if (not value.is_null())
533 throw conversion_error{
534 "Extracting non-null field into nullptr_t variable."};
535 return nullptr;
536}
537
538
540template<> PQXX_LIBEXPORT std::string to_string(field const &value);
541} // namespace pqxx
542#endif
The home of all libpqxx classes, functions, templates, etc.
Definition array.hxx:27
std::basic_ostream< CHAR > & operator<<(std::basic_ostream< CHAR > &s, field const &value)
Write a result field to any type of stream.
Definition field.hxx:495
int row_size_type
Number of fields in a row of database data.
Definition types.hxx:34
std::size_t field_size_type
Number of bytes in a field of database data.
Definition types.hxx:40
int result_size_type
Number of rows in a result set.
Definition types.hxx:28
constexpr bool is_null(TYPE const &value) noexcept
Is value null?
Definition strconv.hxx:370
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:35
std::nullptr_t from_string< std::nullptr_t >(field const &value)
Convert a field's value to nullptr_t.
Definition field.hxx:530
std::string to_string(field const &value)
Convert a field to a string.
Definition result.cxx:533
T from_string(field const &value)
Convert a field's value to type T.
Definition field.hxx:506
void PQXX_COLD throw_null_conversion(std::string const &type)
Definition strconv.cxx:253
Low-level array parser.
Definition array.hxx:48
Value conversion failed, e.g. when converting "Hello" to int.
Definition except.hxx:188
Reference to a field in a result set.
Definition field.hxx:35
array_parser as_array() const &
Parse the field as an SQL array.
Definition field.hxx:255
constexpr result const & home() const noexcept
Definition field.hxx:263
PQXX_PURE size_type size() const noexcept
Return number of bytes taken up by the field's value.
Definition field.cxx:77
T as(T const &default_value) const
Return value as object of given type, or default value if null.
Definition field.hxx:208
row_size_type m_col
Definition field.hxx:280
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:192
field_size_type size_type
Definition field.hxx:37
bool operator>>(T &obj) const
Read value into obj; or leave obj untouched and return false if null.
Definition field.hxx:178
PQXX_PURE char const * c_str() const &
Read as plain C string.
Definition field.cxx:65
T as() const
Return value as object of given type, or throw exception if null.
Definition field.hxx:222
field(result const &r, result_size_type row_num, row_size_type col_num) noexcept
Definition field.hxx:270
constexpr row_size_type col() const noexcept
Definition field.hxx:265
PQXX_PURE std::string_view view() const &
Read as string_view, or an empty one if null.
Definition field.hxx:114
bool composite_to(T &...fields) const
Read field as a composite value, write its components into fields.
Definition field.hxx:164
field() noexcept=default
Constructor. Do not call this yourself; libpqxx will do it for you.
PQXX_PURE bool is_null() const noexcept
Is this field's value null?
Definition field.cxx:71
constexpr O< T > get() const
Return value wrapped in some optional type (empty for nulls).
Definition field.hxx:242
constexpr result::size_type idx() const noexcept
Definition field.hxx:264
Definition field.hxx:402
TRAITS traits_type
Definition field.hxx:405
typename traits_type::off_type off_type
Definition field.hxx:408
field_streambuf(field const &f)
Definition field.hxx:412
virtual pos_type seekoff(off_type, seekdir, openmode) override
Definition field.hxx:417
virtual pos_type seekpos(pos_type, openmode) override
Definition field.hxx:421
std::ios::openmode openmode
Definition field.hxx:409
virtual int_type overflow(int_type) override
Definition field.hxx:425
typename traits_type::pos_type pos_type
Definition field.hxx:407
virtual int sync() override
Definition field.hxx:415
typename traits_type::int_type int_type
Definition field.hxx:406
virtual int_type underflow() override
Definition field.hxx:426
CHAR char_type
Definition field.hxx:404
std::ios::seekdir seekdir
Definition field.hxx:410
Input stream that gets its data from a result field.
Definition field.hxx:451
TRAITS traits_type
Definition field.hxx:456
basic_fieldstream(field const &f)
Definition field.hxx:461
typename traits_type::pos_type pos_type
Definition field.hxx:458
typename traits_type::off_type off_type
Definition field.hxx:459
typename traits_type::int_type int_type
Definition field.hxx:457
CHAR char_type
Definition field.hxx:455
Result set containing data returned by a query or command.
Definition result.hxx:74
result_size_type size_type
Definition result.hxx:76
Reference to one row in a result.
Definition row.hxx:47
Traits describing a type's "null value," if any.
Definition strconv.hxx:93
Marker-type wrapper: zero-terminated std::string_view.
Definition zview.hxx:38