7#include <userver/storages/postgres/exceptions.hpp>
8#include <userver/storages/postgres/io/buffer_io.hpp>
9#include <userver/storages/postgres/io/buffer_io_base.hpp>
10#include <userver/storages/postgres/io/nullable_traits.hpp>
12#include <userver/utils/strong_typedef.hpp>
14USERVER_NAMESPACE_BEGIN
22template <
typename Tag,
typename T, USERVER_NAMESPACE::
utils::StrongTypedefOps Ops>
23concept IsStrongTypedefDirectlyMapped =
30template <
typename Tag,
typename T, USERVER_NAMESPACE::
utils::StrongTypedefOps Ops>
33 : BoolConstant<impl::IsStrongTypedefDirectlyMapped<Tag, T, Ops> ||
kIsMappedToPg<T>> {};
37template <
typename Tag,
typename T, USERVER_NAMESPACE::
utils::StrongTypedefOps Ops>
40 : BoolConstant<!impl::IsStrongTypedefDirectlyMapped<Tag, T, Ops> &&
kIsMappedToPg<T>> {};
42template <
typename Tag,
typename T, USERVER_NAMESPACE::
utils::StrongTypedefOps Ops>
45template <
typename Tag,
typename T, USERVER_NAMESPACE::
utils::StrongTypedefOps Ops>
47 using ValueType = USERVER_NAMESPACE::
utils::StrongTypedef<Tag, T, Ops>;
49 inline static bool IsNull(
const ValueType& v) {
return UnderlyingGetSet::IsNull(v.GetUnderlying()); }
50 inline static void SetNull(ValueType& v) { UnderlyingGetSet::SetNull(v.GetUnderlying()); }
51 inline static void SetDefault(ValueType& v) { UnderlyingGetSet::SetDefault(v.GetUnderlying()); }
62constexpr bool CheckCanUseEnumAsStrongTypedef() {
66 "storages::postgres::io::traits::CanUseEnumAsStrongTypedef "
67 "should be specialized only for enums"
70 std::is_signed_v<std::underlying_type_t<T>>,
71 "storages::postgres::io::traits::CanUseEnumAsStrongTypedef should be "
72 "specialized only for enums with signed underlying type"
88template <
typename Tag,
typename T, USERVER_NAMESPACE::
utils::StrongTypedefOps Ops>
90 : detail::BufferFormatterBase<USERVER_NAMESPACE::
utils::StrongTypedef<Tag, T, Ops>> {
91 using BaseType = detail::BufferFormatterBase<USERVER_NAMESPACE::
utils::StrongTypedef<Tag, T, Ops>>;
92 using BaseType::BaseType;
94 template <
typename Buffer>
95 void operator()(
const UserTypes& types, Buffer& buf)
const {
96 io::WriteBuffer(types, buf,
this->value.GetUnderlying());
101template <
typename StrongTypedef,
bool Categories =
false>
102struct StrongTypedefParser : BufferParserBase<StrongTypedef> {
103 using BaseType = BufferParserBase<StrongTypedef>;
104 using UnderlyingType =
typename StrongTypedef::UnderlyingType;
106 using BaseType::BaseType;
109 UnderlyingType& v =
this->value.GetUnderlying();
110 io::ReadBuffer(buffer, v);
114template <
typename StrongTypedef>
115struct StrongTypedefParser<StrongTypedef,
true> : BufferParserBase<StrongTypedef> {
116 using BaseType = BufferParserBase<StrongTypedef>;
117 using UnderlyingType =
typename StrongTypedef::UnderlyingType;
119 using BaseType::BaseType;
121 void operator()(
const FieldBuffer& buffer,
const TypeBufferCategory& categories) {
122 UnderlyingType& v =
this->value.GetUnderlying();
123 io::ReadBuffer(buffer, v, categories);
129template <
typename Tag,
typename T, USERVER_NAMESPACE::
utils::StrongTypedefOps Ops>
131 : detail::StrongTypedefParser<
132 USERVER_NAMESPACE::
utils::StrongTypedef<Tag, T, Ops>,
133 detail::kParserRequiresTypeCategories<T>> {
134 using BaseType = detail::StrongTypedefParser<
135 USERVER_NAMESPACE::
utils::StrongTypedef<Tag, T, Ops>,
136 detail::kParserRequiresTypeCategories<T>>;
137 using BaseType::BaseType;
141template <
typename Tag,
typename T, USERVER_NAMESPACE::
utils::StrongTypedefOps Ops>
147template <
typename Tag,
typename T, USERVER_NAMESPACE::
utils::StrongTypedefOps Ops>
156struct EnumStrongTypedefFormatter : BufferFormatterBase<T> {
157 using BaseType = BufferFormatterBase<T>;
158 using BaseType::BaseType;
160 template <
typename Buffer>
161 void operator()(
const UserTypes& types, Buffer& buf)
const {
162 io::WriteBuffer(types, buf, USERVER_NAMESPACE::
utils::UnderlyingValue(
this->value));
167struct EnumStrongTypedefParser : BufferParserBase<T> {
168 using BaseType = BufferParserBase<T>;
169 using ValueType =
typename BaseType::ValueType;
170 using UnderlyingType = std::underlying_type_t<ValueType>;
172 using BaseType::BaseType;
176 io::ReadBuffer(buffer, v);
177 this->value =
static_cast<ValueType>(v);
187 using type =
io::detail::EnumStrongTypedefFormatter<T>;
192 using type =
io::detail::EnumStrongTypedefParser<T>;