libpqxx 7.7.0
composite.hxx
1#ifndef PQXX_H_COMPOSITE
2#define PQXX_H_COMPOSITE
3
4#include "pqxx/internal/array-composite.hxx"
5#include "pqxx/internal/concat.hxx"
6#include "pqxx/util.hxx"
7
8namespace pqxx
9{
11
30template<typename... T>
31inline void parse_composite(
32 pqxx::internal::encoding_group enc, std::string_view text, T &...fields)
33{
34 static_assert(sizeof...(fields) > 0);
35
36 auto const scan{pqxx::internal::get_glyph_scanner(enc)};
37 auto const data{std::data(text)};
38 auto const size{std::size(text)};
39 if (size == 0)
40 throw conversion_error{"Cannot parse composite value from empty string."};
41
42 std::size_t here{0}, next{scan(data, size, here)};
43 if (next != 1 or data[here] != '(')
44 throw conversion_error{
45 internal::concat("Invalid composite value string: ", text)};
46
47 here = next;
48
49 // C++20: constinit.
50 constexpr auto num_fields{sizeof...(fields)};
51 std::size_t index{0};
52 (pqxx::internal::parse_composite_field(
53 index, text, here, fields, scan, num_fields - 1),
54 ...);
55 if (here != std::size(text))
56 throw conversion_error{internal::concat(
57 "Composite value did not end at the closing parenthesis: '", text,
58 "'.")};
59 if (text[here - 1] != ')')
60 throw conversion_error{internal::concat(
61 "Composive value did not end in parenthesis: '", text, "'")};
62}
63
64
66
71template<typename... T>
72inline void parse_composite(std::string_view text, T &...fields)
73{
74 parse_composite(pqxx::internal::encoding_group::MONOBYTE, text, fields...);
75}
76} // namespace pqxx
77
78
80{
81// C++20: constinit.
82constexpr char empty_composite_str[]{"()"};
83} // namespace pqxx::internal
84
85
86namespace pqxx
87{
89
91template<typename... T>
92[[nodiscard]] inline std::size_t
93composite_size_buffer(T const &...fields) noexcept
94{
95 // C++20: constinit.
96 constexpr auto num{sizeof...(fields)};
97
98 // Size for a multi-field composite includes room for...
99 // + opening parenthesis
100 // + field budgets
101 // + separating comma per field
102 // - comma after final field
103 // + closing parenthesis
104 // + terminating zero
105
106 if constexpr (num == 0)
107 return std::size(pqxx::internal::empty_composite_str);
108 else
109 return 1 + (pqxx::internal::size_composite_field_buffer(fields) + ...) +
110 num + 1;
111}
112
113
115
120template<typename... T>
121inline char *composite_into_buf(char *begin, char *end, T const &...fields)
122{
123 if (std::size_t(end - begin) < composite_size_buffer(fields...))
124 throw conversion_error{
125 "Buffer space may not be enough to represent composite value."};
126
127 // C++20: constinit.
128 constexpr auto num_fields{sizeof...(fields)};
129 if constexpr (num_fields == 0)
130 {
131 // C++20: constinit.
132 constexpr char empty[]{"()"};
133 std::memcpy(begin, empty, std::size(empty));
134 return begin + std::size(empty);
135 }
136
137 char *pos{begin};
138 *pos++ = '(';
139
140 (pqxx::internal::write_composite_field<T>(pos, end, fields), ...);
141
142 // If we've got multiple fields, "backspace" that last comma.
143 if constexpr (num_fields > 1)
144 --pos;
145 *pos++ = ')';
146 *pos++ = '\0';
147 return pos;
148}
149} // namespace pqxx
150#endif
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:23
char * composite_into_buf(char *begin, char *end, T const &...fields)
Render a series of values as a single composite SQL value.
Definition: composite.hxx:121
std::size_t composite_size_buffer(T const &...fields) noexcept
Estimate the buffer size needed to represent a value of a composite type.
Definition: composite.hxx:93
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:31
Internal items for libpqxx' own use. Do not use these yourself.
Definition: composite.hxx:80
PQXX_PURE glyph_scanner_func * get_glyph_scanner(encoding_group enc)
Definition: encodings.cxx:785
constexpr char empty_composite_str[]
Definition: composite.hxx:82
Value conversion failed, e.g. when converting "Hello" to int.
Definition: except.hxx:176