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