userver: userver/storages/postgres/io/string_types.hpp Source File
Loading...
Searching...
No Matches
string_types.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/storages/postgres/io/string_types.hpp
4/// @brief Strings I/O support
5/// @ingroup userver_postgres_parse_and_format
6
7#include <cstring>
8#include <string>
9#include <string_view>
10
11#include <algorithm>
12
13#include <userver/storages/postgres/exceptions.hpp>
14#include <userver/storages/postgres/io/buffer_io_base.hpp>
15#include <userver/storages/postgres/io/traits.hpp>
16#include <userver/storages/postgres/io/type_mapping.hpp>
17
18USERVER_NAMESPACE_BEGIN
19
20namespace storages::postgres::io {
21
22//@{
23/** @name const char* formatting */
24template <>
25struct BufferFormatter<const char*> {
26 const char* value;
27
28 explicit BufferFormatter(const char* val)
29 : value{val}
30 {}
31
32 template <typename Buffer>
33 void operator()(const UserTypes&, Buffer& buf) const {
34 auto sz = std::strlen(value);
35 WriteN(buf, value, sz);
36 }
37
38 template <typename Buffer>
39 static void WriteN(Buffer& buf, const char* c, std::size_t n) {
40 // Don't copy zero-terminator in binary mode
41 while (n > 0 && c[n - 1] == '\0') {
42 --n;
43 }
44 buf.reserve(buf.size() + n);
45 std::copy(c, c + n, std::back_inserter(buf));
46 }
47};
48//@}
49
50//@{
51/** @name char[N] formatting */
52template <std::size_t N>
53struct BufferFormatter<char[N]> {
54 using CharFormatter = BufferFormatter<const char*>;
55 const char* value;
56
57 explicit BufferFormatter(const char* val)
58 : value{val}
59 {}
60
61 template <typename Buffer>
62 void operator()(const UserTypes&, Buffer& buf) const {
63 CharFormatter::WriteN(buf, value, N);
64 }
65};
66
67//@}
68
69//@{
70/** @name std::string I/O */
71template <>
72struct BufferFormatter<std::string> {
73 using CharFormatter = BufferFormatter<const char*>;
74 const std::string& value;
75
76 explicit BufferFormatter(const std::string& val)
77 : value{val}
78 {}
79 template <typename Buffer>
80 void operator()(const UserTypes&, Buffer& buf) const {
81 CharFormatter::WriteN(buf, value.data(), value.size());
82 }
83};
84
85template <>
86struct BufferParser<std::string> {
87 std::string& value;
88
89 explicit BufferParser(std::string& val)
90 : value{val}
91 {}
92
93 void operator()(const FieldBuffer& buffer);
94};
95//@}
96
97//@{
98/** @name string_view I/O */
99template <>
100struct BufferFormatter<std::string_view> : detail::BufferFormatterBase<std::string_view> {
101 using BaseType = detail::BufferFormatterBase<std::string_view>;
102 using CharFormatter = BufferFormatter<const char*>;
103
104 using BaseType::BaseType;
105
106 template <typename Buffer>
107 void operator()(const UserTypes&, Buffer& buffer) const {
108 CharFormatter::WriteN(buffer, value.data(), value.size());
109 }
110};
111
112template <>
113struct BufferParser<std::string_view> : detail::BufferParserBase<std::string_view> {
114 using BaseType = detail::BufferParserBase<std::string_view>;
115 using BaseType::BaseType;
116
117 void operator()(const FieldBuffer& buffer) {
118 using std::swap;
119 ValueType tmp{reinterpret_cast<const char*>(buffer.buffer), buffer.length};
120 swap(tmp, value);
121 }
122};
123//@}
124
125//@{
126/** @name char I/O */
127template <>
128struct BufferFormatter<char> {
129 char value;
130
131 explicit BufferFormatter(char val)
132 : value{val}
133 {}
134 template <typename Buffer>
135 void operator()(const UserTypes&, Buffer& buf) const {
136 buf.push_back(value);
137 }
138};
139
140template <>
141struct BufferParser<char> {
142 char& value;
143
144 explicit BufferParser(char& val)
145 : value{val}
146 {}
147
148 void operator()(const FieldBuffer& buffer) {
149 if (buffer.length != 1) {
150 throw InvalidInputBufferSize{fmt::format("Buffer size {} is invalid for type char", buffer.length)};
151 }
152 value = *buffer.buffer;
153 }
154};
155//@}
156
157//@{
158/** @name C++ to PostgreSQL mapping for string types */
159template <>
160struct CppToSystemPg<const char*> : PredefinedOid<PredefinedOids::kText> {};
161template <std::size_t N>
162struct CppToSystemPg<char[N]> : PredefinedOid<PredefinedOids::kText> {};
163template <>
164struct CppToSystemPg<std::string> : PredefinedOid<PredefinedOids::kText> {};
165template <>
166struct CppToSystemPg<std::string_view> : PredefinedOid<PredefinedOids::kText> {};
167template <>
168struct CppToSystemPg<char> : PredefinedOid<PredefinedOids::kChar> {};
169//@}
170
171} // namespace storages::postgres::io
172
173USERVER_NAMESPACE_END