userver: userver/storages/postgres/io/bytea.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
bytea.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/storages/postgres/io/bytea.hpp
4/// @brief storages::postgres::Bytea I/O support
5/// @ingroup userver_postgres_parse_and_format
6
7#include <string>
8#include <string_view>
9#include <vector>
10
11#include <userver/storages/postgres/exceptions.hpp>
12#include <userver/storages/postgres/io/buffer_io.hpp>
13#include <userver/storages/postgres/io/buffer_io_base.hpp>
14#include <userver/storages/postgres/io/type_mapping.hpp>
15
16USERVER_NAMESPACE_BEGIN
17
18namespace storages::postgres {
19
20namespace io::traits {
21
22template <typename T>
23struct IsByteaCompatible : std::false_type {};
24
25template <>
26struct IsByteaCompatible<std::string> : std::true_type {};
27template <>
29template <typename... VectorArgs>
30struct IsByteaCompatible<std::vector<char, VectorArgs...>> : std::true_type {};
31template <typename... VectorArgs>
32struct IsByteaCompatible<std::vector<unsigned char, VectorArgs...>>
33 : std::true_type {};
34
35template <typename T>
36inline constexpr bool kIsByteaCompatible = IsByteaCompatible<T>::value;
37
38template <typename T>
40
41} // namespace io::traits
42
43namespace detail {
44
45template <typename ByteContainerRef>
46struct ByteaRefWrapper {
47 static_assert(std::is_reference<ByteContainerRef>::value,
48 "The container must be passed by reference");
49
50 using BytesType = std::decay_t<ByteContainerRef>;
51 static_assert(
52 io::traits::kIsByteaCompatible<BytesType>,
53 "This C++ type cannot be used with PostgreSQL `bytea` data type");
54
55 ByteContainerRef bytes;
56};
57
58} // namespace detail
59
60/// Helper function for writing binary data
61template <typename ByteContainer>
62detail::ByteaRefWrapper<const ByteContainer&> Bytea(
63 const ByteContainer& bytes) {
64 return {bytes};
65}
66
67/// Helper function for reading binary data
68template <typename ByteContainer>
69detail::ByteaRefWrapper<ByteContainer&> Bytea(ByteContainer& bytes) {
70 return {bytes};
71}
72
73/// Wrapper for binary data container
74template <typename ByteContainer>
77
78 static_assert(
80 "This C++ type cannot be used with PostgreSQL `bytea` data type");
81
82 ByteContainer bytes;
83};
84
85namespace io {
86
87template <typename ByteContainer>
88struct BufferParser<
95 using BaseType::BaseType;
97
98 void operator()(const FieldBuffer& buffer) {
99 if constexpr (std::is_same<typename ByteaType::BytesType,
100 std::string_view>{}) {
101 this->value.bytes = std::string_view{
102 reinterpret_cast<const char*>(buffer.buffer), buffer.length};
103 } else {
106 this->value.bytes.begin());
107 }
108 }
109};
110
111template <typename ByteContainer>
116 using BaseType =
118 using BaseType::BaseType;
119
120 void operator()(const FieldBuffer& buffer) {
122 }
123};
124
125template <typename ByteContainer>
126struct BufferFormatter<
133 using BaseType::BaseType;
134
135 template <typename Buffer>
136 void operator()(const UserTypes&, Buffer& buf) const {
137 buf.reserve(buf.size() + this->value.bytes.size());
138 buf.insert(buf.end(), this->value.bytes.begin(), this->value.bytes.end());
139 }
140};
141
142template <typename ByteContainer>
147 using BaseType =
149 using BaseType::BaseType;
150
151 template <typename Buffer>
152 void operator()(const UserTypes& types, Buffer& buffer) const {
154 }
155};
156
157template <typename ByteContainer>
158struct CppToSystemPg<postgres::detail::ByteaRefWrapper<ByteContainer>>
159 : PredefinedOid<PredefinedOids::kBytea> {};
160template <typename ByteContainer>
161struct CppToSystemPg<postgres::ByteaWrapper<ByteContainer>>
162 : PredefinedOid<PredefinedOids::kBytea> {};
163
164} // namespace io
165} // namespace storages::postgres
166
167USERVER_NAMESPACE_END