libpqxx 7.9.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-2024, 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
35{
36public:
38
44
60 [[nodiscard]] PQXX_PURE bool operator==(field const &) const noexcept;
61
63
65 [[nodiscard]] PQXX_PURE bool operator!=(field const &rhs) const noexcept
66 {
67 return not operator==(rhs);
68 }
70
76 [[nodiscard]] PQXX_PURE char const *name() const &;
77
79 [[nodiscard]] oid PQXX_PURE type() const;
80
82 [[nodiscard]] PQXX_PURE oid table() const;
83
86
88 [[nodiscard]] PQXX_PURE row_size_type table_column() const;
90
107
111 [[nodiscard]] PQXX_PURE std::string_view view() const &
112 {
113 return std::string_view(c_str(), size());
114 }
115
117
126 [[nodiscard]] PQXX_PURE char const *c_str() const &;
127
130
132 [[nodiscard]] PQXX_PURE size_type size() const noexcept;
133
135
140 (not std::is_pointer<T>::value or std::is_same<T, char const *>::value),
141 bool>
142 {
143 if (is_null())
144 {
145 return false;
146 }
147 else
148 {
149 auto const data{c_str()};
150 from_string(data, obj);
151 return true;
152 }
153 }
154
156
161 template<typename... T> bool composite_to(T &...fields) const
162 {
163 if (is_null())
164 {
165 return false;
166 }
167 else
168 {
169 parse_composite(m_home.m_encoding, view(), fields...);
170 return true;
171 }
172 }
173
175 template<typename T> bool operator>>(T &obj) const { return to(obj); }
176
178
188 template<typename T>
189 auto to(T &obj, T const &default_value) const -> typename std::enable_if_t<
190 (not std::is_pointer<T>::value or std::is_same<T, char const *>::value),
191 bool>
192 {
193 bool const null{is_null()};
194 if (null)
196 else
197 obj = from_string<T>(this->view());
198 return not null;
199 }
200
202
205 template<typename T> T as(T const &default_value) const
206 {
207 if (is_null())
208 return default_value;
209 else
210 return from_string<T>(this->view());
211 }
212
214
219 template<typename T> T as() const
220 {
221 if (is_null())
222 {
223 if constexpr (not nullness<T>::has_null)
225 else
226 return nullness<T>::null();
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
258
262 [[deprecated(
263 "Do not construct fields yourself. Get them from the row.")]] field(row const &r, row_size_type c) noexcept;
264
266 [[deprecated(
267 "Do not construct fields yourself. Get them from the "
268 "row.")]] field() noexcept = default;
269
270
272 constexpr result const &home() const noexcept { return m_home; }
273 constexpr result::size_type idx() const noexcept { return m_row; }
274 constexpr row_size_type col() const noexcept { return m_col; }
275
276 // TODO: Create gates.
277 friend class pqxx::result;
278 friend class pqxx::row;
281 :
282 m_col{col_num}, m_home{r}, m_row{row_num}
283 {}
284
290
291private:
292 result m_home;
293 result::size_type m_row;
294};
295
296
297template<> inline bool field::to<std::string>(std::string &obj) const
298{
299 bool const null{is_null()};
300 if (not null)
301 obj = std::string{view()};
302 return not null;
303}
304
305
306template<>
307inline bool field::to<std::string>(
308 std::string &obj, std::string const &default_value) const
309{
310 bool const null{is_null()};
311 if (null)
313 else
314 obj = std::string{view()};
315 return not null;
316}
317
318
320
325template<> inline bool field::to<char const *>(char const *&obj) const
326{
327 bool const null{is_null()};
328 if (not null)
329 obj = c_str();
330 return not null;
331}
332
333
334template<> inline bool field::to<std::string_view>(std::string_view &obj) const
335{
336 bool const null{is_null()};
337 if (not null)
338 obj = view();
339 return not null;
340}
341
342
343template<>
344inline bool field::to<std::string_view>(
345 std::string_view &obj, std::string_view const &default_value) const
346{
347 bool const null{is_null()};
348 if (null)
350 else
351 obj = view();
352 return not null;
353}
354
355
356template<> inline std::string_view field::as<std::string_view>() const
357{
358 if (is_null())
361 return view();
362}
363
364
365template<>
366inline std::string_view
367field::as<std::string_view>(std::string_view const &default_value) const
368{
369 return is_null() ? default_value : view();
370}
371
372
373template<> inline bool field::to<zview>(zview &obj) const
374{
375 bool const null{is_null()};
376 if (not null)
377 obj = zview{c_str(), size()};
378 return not null;
379}
380
381
382template<>
383inline bool field::to<zview>(zview &obj, zview const &default_value) const
384{
385 bool const null{is_null()};
386 if (null)
388 else
389 obj = zview{c_str(), size()};
390 return not null;
391}
392
393
394template<> inline zview field::as<zview>() const
395{
396 if (is_null())
399 return zview{c_str(), size()};
400}
401
402
403template<> inline zview field::as<zview>(zview const &default_value) const
404{
405 return is_null() ? default_value : zview{c_str(), size()};
406}
407
408
409template<typename CHAR = char, typename TRAITS = std::char_traits<CHAR>>
410class field_streambuf : public std::basic_streambuf<CHAR, TRAITS>
411{
412public:
415 using int_type = typename traits_type::int_type;
416 using pos_type = typename traits_type::pos_type;
417 using off_type = typename traits_type::off_type;
418 using openmode = std::ios::openmode;
419 using seekdir = std::ios::seekdir;
420
421 explicit field_streambuf(field const &f) : m_field{f} { initialize(); }
422
423protected:
424 virtual int sync() override { return traits_type::eof(); }
425
427 {
428 return traits_type::eof();
429 }
431 {
432 return traits_type::eof();
433 }
434 virtual int_type overflow(int_type) override { return traits_type::eof(); }
435 virtual int_type underflow() override { return traits_type::eof(); }
436
437private:
438 field const &m_field;
439
440 int_type initialize()
441 {
442 auto g{static_cast<char_type *>(const_cast<char *>(m_field.c_str()))};
443 this->setg(g, g, g + std::size(m_field));
444 return int_type(std::size(m_field));
445 }
446};
447
448
450
463template<typename CHAR = char, typename TRAITS = std::char_traits<CHAR>>
464class basic_fieldstream : public std::basic_istream<CHAR, TRAITS>
465{
466 using super = std::basic_istream<CHAR, TRAITS>;
467
468public:
471 using int_type = typename traits_type::int_type;
472 using pos_type = typename traits_type::pos_type;
473 using off_type = typename traits_type::off_type;
474
475 [[deprecated("Use field::as<...>() or field::c_str().")]] basic_fieldstream(
476 field const &f) :
477 super{nullptr}, m_buf{f}
478 {
479 super::init(&m_buf);
480 }
481
482private:
484};
485
486
489
490
492
516template<typename CHAR>
517[[deprecated(
518 "Do this by hand, probably with better error checking.")]] inline std::
519 basic_ostream<CHAR> &
520 operator<<(std::basic_ostream<CHAR> &s, field const &value)
521{
522 s.write(value.c_str(), std::streamsize(std::size(value)));
523 return s;
524}
525
526
528
531template<typename T> inline T from_string(field const &value)
532{
533 if (value.is_null())
534 {
535 if constexpr (nullness<T>::has_null)
536 return nullness<T>::null();
537 else
539 }
540 else
541 {
542 return from_string<T>(value.view());
543 }
544}
545
546
548
554template<>
555inline std::nullptr_t from_string<std::nullptr_t>(field const &value)
556{
557 if (not value.is_null())
558 throw conversion_error{
559 "Extracting non-null field into nullptr_t variable."};
560 return nullptr;
561}
562
563
565template<> PQXX_LIBEXPORT std::string to_string(field const &value);
566} // namespace pqxx
567#endif
The home of all libpqxx classes, functions, templates, etc.
Definition array.hxx:33
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:520
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 char array_separator
Element separator between SQL array elements of this type.
Definition strconv.hxx:557
int row_size_type
Number of fields in a row of database data.
Definition types.hxx:34
constexpr bool is_null(TYPE const &value) noexcept
Is value null?
Definition strconv.hxx:513
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:555
std::string to_string(field const &value)
Convert a field to a string.
Definition result.cxx:566
T from_string(field const &value)
Convert a field's value to type T.
Definition field.hxx:531
void PQXX_COLD throw_null_conversion(std::string const &type)
Definition strconv.cxx:253
Low-level array parser.
Definition array.hxx:527
Value conversion failed, e.g. when converting "Hello" to int.
Definition except.hxx:283
Reference to a field in a result set.
Definition field.hxx:35
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:205
row_size_type m_col
Definition field.hxx:289
array_parser as_array() const &noexcept
Parse the field as an SQL array.
Definition field.hxx:251
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:189
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:175
PQXX_PURE bool operator!=(field const &rhs) const noexcept
Byte-by-byte comparison (all nulls are considered equal)
Definition field.hxx:65
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:219
field(result const &r, result_size_type row_num, row_size_type col_num) noexcept
Definition field.hxx:279
constexpr row_size_type col() const noexcept
Definition field.hxx:274
PQXX_PURE std::string_view view() const &
Read as string_view, or an empty one if null.
Definition field.hxx:111
bool composite_to(T &...fields) const
Read field as a composite value, write its components into fields.
Definition field.hxx:161
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:239
constexpr result::size_type idx() const noexcept
Definition field.hxx:273
Definition field.hxx:411
TRAITS traits_type
Definition field.hxx:414
typename traits_type::off_type off_type
Definition field.hxx:417
field_streambuf(field const &f)
Definition field.hxx:421
virtual pos_type seekoff(off_type, seekdir, openmode) override
Definition field.hxx:426
virtual pos_type seekpos(pos_type, openmode) override
Definition field.hxx:430
std::ios::openmode openmode
Definition field.hxx:418
virtual int_type overflow(int_type) override
Definition field.hxx:434
typename traits_type::pos_type pos_type
Definition field.hxx:416
virtual int sync() override
Definition field.hxx:424
typename traits_type::int_type int_type
Definition field.hxx:415
virtual int_type underflow() override
Definition field.hxx:435
CHAR char_type
Definition field.hxx:413
std::ios::seekdir seekdir
Definition field.hxx:419
Input stream that gets its data from a result field.
Definition field.hxx:465
TRAITS traits_type
Definition field.hxx:470
basic_fieldstream(field const &f)
Definition field.hxx:475
typename traits_type::pos_type pos_type
Definition field.hxx:472
typename traits_type::off_type off_type
Definition field.hxx:473
typename traits_type::int_type int_type
Definition field.hxx:471
CHAR char_type
Definition field.hxx:469
Result set containing data returned by a query or command.
Definition result.hxx:73
result_size_type size_type
Definition result.hxx:75
Reference to one row in a result.
Definition row.hxx:47
Traits describing a type's "null value," if any.
Definition strconv.hxx:91
static TYPE null()
Return a null value.
Marker-type wrapper: zero-terminated std::string_view.
Definition zview.hxx:38