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