userver: userver/cache/mongo_cache_type_traits.hpp Source File
Loading...
Searching...
No Matches
mongo_cache_type_traits.hpp
1#pragma once
2
3#include <chrono>
4#include <type_traits>
5
6#include <userver/cache/update_type.hpp>
7#include <userver/utils/meta.hpp>
8#include <userver/utils/void_t.hpp>
9
10USERVER_NAMESPACE_BEGIN
11
12namespace formats::bson {
13class Document;
14}
15
16namespace storages::mongo::operations {
17class Find;
18}
19
20namespace mongo_cache::impl {
21
22template <typename T>
23using CollectionsField = decltype(T::kMongoCollectionsField);
24template <typename T>
25inline constexpr bool kHasCollectionsField =
26 meta::kIsDetected<CollectionsField, T>;
27
28template <typename T>
29using UpdateFieldName = decltype(T::kMongoUpdateFieldName);
30template <typename T>
31inline constexpr bool kHasUpdateFieldName =
32 meta::kIsDetected<UpdateFieldName, T>;
33
34template <typename T>
35using KeyField = decltype(T::kKeyField);
36template <typename T>
37inline constexpr bool kHasKeyField = meta::kIsDetected<KeyField, T>;
38
39template <typename T>
40using DataType = typename T::DataType;
41template <typename T>
42inline constexpr bool kHasValidDataType =
43 meta::kIsMap<meta::DetectedType<DataType, T>>;
44
45template <typename T>
46using HasSecondaryPreferred = decltype(T::kIsSecondaryPreferred);
47template <typename T>
48inline constexpr bool kHasSecondaryPreferred =
49 meta::kIsDetected<HasSecondaryPreferred, T>;
50
51template <typename T>
52using HasDeserializeObject = decltype(T::DeserializeObject);
53template <typename T>
54inline constexpr bool kHasDeserializeObject =
55 meta::kIsDetected<HasDeserializeObject, T>;
56
57template <typename T>
58using HasCorrectDeserializeObject =
59 meta::ExpectSame<typename T::ObjectType,
60 decltype(std::declval<const T&>().DeserializeObject(
61 std::declval<const formats::bson::Document&>()))>;
62template <typename T>
63inline constexpr bool kHasCorrectDeserializeObject =
64 meta::kIsDetected<HasCorrectDeserializeObject, T>;
65
66template <typename T>
67using HasDefaultDeserializeObject = decltype(T::kUseDefaultDeserializeObject);
68template <typename T>
69inline constexpr bool kHasDefaultDeserializeObject =
70 meta::kIsDetected<HasDefaultDeserializeObject, T>;
71
72template <typename T>
73using HasFindOperation = decltype(T::GetFindOperation);
74template <typename T>
75inline constexpr bool kHasFindOperation =
76 meta::kIsDetected<HasFindOperation, T>;
77
78template <typename T>
79using HasCorrectFindOperation = meta::ExpectSame<
80 storages::mongo::operations::Find,
81 decltype(std::declval<const T&>().GetFindOperation(
82 std::declval<cache::UpdateType>(),
83 std::declval<const std::chrono::system_clock::time_point&>(),
84 std::declval<const std::chrono::system_clock::time_point&>(),
85 std::declval<const std::chrono::system_clock::duration&>()))>;
86
87template <typename T>
88inline constexpr bool kHasCorrectFindOperation =
89 meta::kIsDetected<HasCorrectFindOperation, T>;
90
91template <typename T>
92using HasDefaultFindOperation = decltype(T::kUseDefaultFindOperation);
93template <typename T>
94inline constexpr bool kHasDefaultFindOperation =
95 meta::kIsDetected<HasDefaultFindOperation, T>;
96
97template <typename T>
98using HasInvalidDocumentsSkipped = decltype(T::kAreInvalidDocumentsSkipped);
99template <typename T>
100inline constexpr bool kHasInvalidDocumentsSkipped =
101 meta::kIsDetected<HasInvalidDocumentsSkipped, T>;
102
103template <typename>
104struct ClassByMemberPointer {};
105template <typename T, typename C>
106struct ClassByMemberPointer<T C::*> {
107 using type = C;
108};
109template <typename CollectionPtr>
110using CollectionsType =
111 typename ClassByMemberPointer<std::remove_cv_t<CollectionPtr>>::type;
112
113template <typename MongoCacheTraits>
114struct CheckTraits {
115 CheckTraits() {
116 if constexpr (kHasDefaultDeserializeObject<MongoCacheTraits>) {
117 static_assert(
118 std::is_same_v<
119 std::decay_t<
120 decltype(MongoCacheTraits::kUseDefaultDeserializeObject)>,
121 bool>,
122 "Mongo cache traits must specify kUseDefaultDeserializeObject as "
123 "bool");
124 }
125 if constexpr (kHasDefaultFindOperation<MongoCacheTraits>) {
126 static_assert(
127 std::is_same_v<
128 std::decay_t<
129 decltype(MongoCacheTraits::kUseDefaultFindOperation)>,
130 bool>,
131 "Mongo cache traits must specify kUseDefaultFindOperation as bool");
132 }
133 }
134
135 static_assert(kHasCollectionsField<MongoCacheTraits>,
136 "Mongo cache traits must specify collections field");
137 static_assert(kHasKeyField<MongoCacheTraits>,
138 "Mongo cache traits must specify key field");
139 static_assert(kHasValidDataType<MongoCacheTraits>,
140 "Mongo cache traits must specify mapping data type");
141
142 static_assert(kHasSecondaryPreferred<MongoCacheTraits>,
143 "Mongo cache traits must specify read preference");
144 static_assert(
145 std::is_same_v<
146 std::decay_t<decltype(MongoCacheTraits::kIsSecondaryPreferred)>,
147 bool>,
148 "Mongo cache traits must specify read preference of a bool type");
149
150 static_assert(kHasInvalidDocumentsSkipped<MongoCacheTraits>,
151 "Mongo cache traits must specify validation policy");
152 static_assert(
153 std::is_same_v<
154 std::decay_t<decltype(MongoCacheTraits::kAreInvalidDocumentsSkipped)>,
155 bool>,
156 "Mongo cache traits must specify validation policy of a bool type");
157
158 static_assert(kHasFindOperation<MongoCacheTraits> ||
159 kHasDefaultFindOperation<MongoCacheTraits>,
160 "Mongo cache traits must specify find operation");
161 static_assert(!kHasFindOperation<MongoCacheTraits> ||
162 kHasCorrectFindOperation<MongoCacheTraits>,
163 "Mongo cache traits must specify find operation with correct "
164 "signature and return value type: "
165 "static storages::mongo::operations::Find GetFindOperation("
166 "cache::UpdateType type, "
167 "const std::chrono::system_clock::time_point& last_update, "
168 "const std::chrono::system_clock::time_point& now, "
169 "const std::chrono::system_clock::duration& correction)");
170
171 static_assert(kHasDeserializeObject<MongoCacheTraits> ||
172 kHasDefaultDeserializeObject<MongoCacheTraits>,
173 "Mongo cache traits must specify deserialize object");
174 static_assert(
175 !kHasDeserializeObject<MongoCacheTraits> ||
176 kHasCorrectDeserializeObject<MongoCacheTraits>,
177 "Mongo cache traits must specify deserialize object with correct "
178 "signature and return value type: "
179 "static ObjectType DeserializeObject(const formats::bson::Document& "
180 "doc)");
181};
182
183} // namespace mongo_cache::impl
184
185USERVER_NAMESPACE_END