9#include <userver/utils/assert.hpp>
10#include <userver/utils/optional_ref.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/nullable_traits.hpp>
15#include <userver/storages/postgres/io/traits.hpp>
17#include <boost/optional/optional_fwd.hpp>
19USERVER_NAMESPACE_BEGIN
25template <
template <
typename>
class Optional,
typename T,
bool Categories =
false>
26struct OptionalValueParser : BufferParserBase<Optional<T>> {
27 using BaseType = BufferParserBase<Optional<T>>;
28 using ValueParser =
typename traits::
IO<T>::ParserType;
30 using BaseType::BaseType;
34 ValueParser{val}(buffer);
35 this->value = std::move(val);
39template <
template <
typename>
class Optional,
typename T>
40struct OptionalValueParser<Optional, T,
true> : BufferParserBase<Optional<T>> {
41 using BaseType = BufferParserBase<Optional<T>>;
42 using ValueParser =
typename traits::IO<T>::ParserType;
44 using BaseType::BaseType;
46 void operator()(
const FieldBuffer& buffer,
const TypeBufferCategory& categories) {
48 ValueParser{val}(buffer, categories);
49 this->value = std::move(val);
53template <
template <
typename>
class Optional,
typename T>
54struct OptionalValueFormatter : BufferFormatterBase<Optional<T>> {
55 using BaseType = BufferFormatterBase<Optional<T>>;
56 using ValueFormatter =
typename traits::
IO<T>::FormatterType;
58 using BaseType::BaseType;
60 template <
typename Buffer>
61 void operator()(
const UserTypes& types, Buffer& buffer)
const {
63 ValueFormatter{*
this->value}(types, buffer);
72struct BufferParser<boost::optional<T>, std::enable_if_t<traits::kHasParser<T>>>
73 : detail::OptionalValueParser<boost::optional, T, detail::kParserRequiresTypeCategories<T>> {
74 using BaseType = detail::OptionalValueParser<boost::optional, T, detail::kParserRequiresTypeCategories<T>>;
75 using BaseType::BaseType;
80struct BufferFormatter<boost::optional<T>, std::enable_if_t<traits::kHasFormatter<T>>>
81 : detail::OptionalValueFormatter<boost::optional, T> {
82 using BaseType = detail::OptionalValueFormatter<boost::optional, T>;
83 using BaseType::BaseType;
88struct BufferParser<std::optional<T>, std::enable_if_t<traits::kHasParser<T>>>
89 : detail::OptionalValueParser<std::optional, T, detail::kParserRequiresTypeCategories<T>> {
90 using BaseType = detail::OptionalValueParser<std::optional, T, detail::kParserRequiresTypeCategories<T>>;
91 using BaseType::BaseType;
96struct BufferFormatter<std::optional<T>, std::enable_if_t<traits::kHasFormatter<T>>>
97 : detail::OptionalValueFormatter<std::optional, T> {
98 using BaseType = detail::OptionalValueFormatter<std::optional, T>;
99 using BaseType::BaseType;
104struct BufferFormatter<USERVER_NAMESPACE::utils::OptionalRef<T>, std::enable_if_t<traits::kHasFormatter<T>>>
105 : detail::OptionalValueFormatter<USERVER_NAMESPACE::utils::OptionalRef, T> {
106 using BaseType = detail::OptionalValueFormatter<USERVER_NAMESPACE::utils::OptionalRef, T>;
107 using BaseType::BaseType;
112struct CppToPg<boost::optional<T>, std::enable_if_t<traits::kIsMappedToPg<T>>> : CppToPg<T> {};
116struct CppToPg<std::optional<T>, std::enable_if_t<traits::kIsMappedToPg<T>>> : CppToPg<T> {};
120struct CppToPg<USERVER_NAMESPACE::utils::OptionalRef<T>, std::enable_if_t<traits::kIsMappedToPg<T>>> : CppToPg<T> {};
130 using ValueType = boost::optional<T>;
131 inline static bool IsNull(
const ValueType& v) {
return !v; }
132 inline static void SetNull(ValueType& v) { v = ValueType{}; }
133 inline static void SetDefault(ValueType& v) { v.emplace(); }
151 using ValueType = std::optional<T>;
152 inline static bool IsNull(
const ValueType& v) {
return !v; }
153 inline static void SetNull(ValueType& v) { v = std::nullopt; }
154 inline static void SetDefault(ValueType& v) { v.emplace(); }
173 inline static bool IsNull(
const ValueType& v) {
return !v; }
174 inline static void SetNull(ValueType&) {
static_assert(!
sizeof(T),
"SetNull not enabled for utils::OptionalRef"); }
175 inline static void SetDefault(ValueType&) {
176 static_assert(!
sizeof(T),
"SetDefault not enabled for utils::OptionalRef");