libpqxx
The C++ client library for PostgreSQL
Loading...
Searching...
No Matches
composite.hxx
Go to the documentation of this file.
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 <optional>
11#include "pqxx/util.hxx"
12
13namespace pqxx
14{
16
35template<typename... T>
36inline void parse_composite(
37 pqxx::internal::encoding_group enc, std::string_view text, T &...fields)
38{
39 static_assert(sizeof...(fields) > 0);
40
41 auto const scan{pqxx::internal::get_glyph_scanner(enc)};
42 auto const data{std::data(text)};
43 auto const size{std::size(text)};
44 if (size == 0)
45 throw conversion_error{"Cannot parse composite value from empty string."};
46
47 std::size_t here{0}, next{scan(data, size, here)};
48 if (next != 1 or data[here] != '(')
49 throw conversion_error{
50 internal::concat("Invalid composite value string: ", text)};
51
52 here = next;
53
54 // TODO: Reuse parse_composite_field specialisation across calls.
55 constexpr auto num_fields{sizeof...(fields)};
56 std::size_t index{0};
58 index, text, here, fields, num_fields - 1),
59 ...);
60 if (here != std::size(text))
62 "Composite value did not end at the closing parenthesis: '", text,
63 "'.")};
64 if (text[here - 1] != ')')
66 "Composive value did not end in parenthesis: '", text, "'")};
67}
68
69
71
76template<typename... T>
77inline void parse_composite(std::string_view text, T &...fields)
78{
80}
81} // namespace pqxx
82
83
84namespace pqxx::internal
85{
86constexpr char empty_composite_str[]{"()"};
87} // namespace pqxx::internal
88
89
90namespace pqxx
91{
93
95template<typename... T>
96[[nodiscard]] inline std::size_t
97composite_size_buffer(T const &...fields) noexcept
98{
99 constexpr auto num{sizeof...(fields)};
100
101 // Size for a multi-field composite includes room for...
102 // + opening parenthesis
103 // + field budgets
104 // + separating comma per field
105 // - comma after final field
106 // + closing parenthesis
107 // + terminating zero
108
109 if constexpr (num == 0)
110 return std::size(pqxx::internal::empty_composite_str);
111 else
112 return 1 + (pqxx::internal::size_composite_field_buffer(fields) + ...) +
113 num + 1;
114}
115
116
118
123template<typename... T>
124inline char *composite_into_buf(char *begin, char *end, T const &...fields)
125{
126 if (std::size_t(end - begin) < composite_size_buffer(fields...))
127 throw conversion_error{
128 "Buffer space may not be enough to represent composite value."};
129
130 constexpr auto num_fields{sizeof...(fields)};
131 if constexpr (num_fields == 0)
132 {
133 constexpr char empty[]{"()"};
134 std::memcpy(begin, empty, std::size(empty));
135 return begin + std::size(empty);
136 }
137
138 char *pos{begin};
139 *pos++ = '(';
140
141 (pqxx::internal::write_composite_field<T>(pos, end, fields), ...);
142
143 // If we've got multiple fields, "backspace" that last comma.
144 if constexpr (num_fields > 1)
145 --pos;
146 *pos++ = ')';
147 *pos++ = '\0';
148 return pos;
149}
150} // namespace pqxx
151#endif
Value conversion failed, e.g. when converting "Hello" to int.
Definition except.hxx:283
Internal items for libpqxx' own use. Do not use these yourself.
Definition encodings.cxx:33
std::string concat(TYPE... item)
Efficiently combine a bunch of items into one big string.
Definition concat.hxx:31
std::size_t size_composite_field_buffer(T const &field)
Conservatively estimate buffer size needed for a composite field.
Definition array-composite.hxx:309
encoding_group
Definition encoding_group.hxx:19
@ MONOBYTE
Definition encoding_group.hxx:21
PQXX_LIBEXPORT glyph_scanner_func * get_glyph_scanner(encoding_group)
Look up the glyph scanner function for a given encoding group.
void write_composite_field(char *&pos, char *end, T const &field)
Definition array-composite.hxx:330
composite_field_parser< T > specialize_parse_composite_field(encoding_group enc)
Look up implementation of parse_composite_field for ENC.
Definition array-composite.hxx:274
constexpr char empty_composite_str[]
Definition composite.hxx:86
The home of all libpqxx classes, functions, templates, etc.
Definition array.cxx: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:124
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:97
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:36
@ text
Definition types.hxx:71