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