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 = meta::kIsDetected<CollectionsField, T>;
26
27template <typename T>
28using UpdateFieldName = decltype(T::kMongoUpdateFieldName);
29template <typename T>
30inline constexpr bool kHasUpdateFieldName = meta::kIsDetected<UpdateFieldName, T>;
31
32template <typename T>
33using KeyField = decltype(T::kKeyField);
34template <typename T>
35inline constexpr bool kHasKeyField = meta::kIsDetected<KeyField, T>;
36
37template <typename T>
38using DataType = typename T::DataType;
39template <typename T>
40inline constexpr bool kHasValidDataType = meta::kIsMap<meta::DetectedType<DataType, T>>;
41
42template <typename T>
43using HasSecondaryPreferred = decltype(T::kIsSecondaryPreferred);
44template <typename T>
45inline constexpr bool kHasSecondaryPreferred = meta::kIsDetected<HasSecondaryPreferred, T>;
46
47template <typename T>
48using HasDeserializeObject = decltype(T::DeserializeObject);
49template <typename T>
50inline constexpr bool kHasDeserializeObject = meta::kIsDetected<HasDeserializeObject, T>;
51
52template <typename T>
53using HasCorrectDeserializeObject = meta::ExpectSame<
54 typename T::ObjectType,
55 decltype(std::declval<const T&>().DeserializeObject(std::declval<const formats::bson::Document&>()))>;
56template <typename T>
57inline constexpr bool kHasCorrectDeserializeObject = meta::kIsDetected<HasCorrectDeserializeObject, T>;
58
59template <typename T>
60using HasDefaultDeserializeObject = decltype(T::kUseDefaultDeserializeObject);
61template <typename T>
62inline constexpr bool kHasDefaultDeserializeObject = meta::kIsDetected<HasDefaultDeserializeObject, T>;
63
64template <typename T>
65using HasFindOperation = decltype(T::GetFindOperation);
66template <typename T>
67inline constexpr bool kHasFindOperation = meta::kIsDetected<HasFindOperation, T>;
68
69template <typename T>
70using HasCorrectFindOperation = meta::ExpectSame<
71 storages::mongo::operations::Find,
72 decltype(std::declval<const T&>().GetFindOperation(
73 std::declval<cache::UpdateType>(),
74 std::declval<const std::chrono::system_clock::time_point&>(),
75 std::declval<const std::chrono::system_clock::time_point&>(),
76 std::declval<const std::chrono::system_clock::duration&>()
77 ))>;
78
79template <typename T>
80inline constexpr bool kHasCorrectFindOperation = meta::kIsDetected<HasCorrectFindOperation, T>;
81
82template <typename T>
83using HasDefaultFindOperation = decltype(T::kUseDefaultFindOperation);
84template <typename T>
85inline constexpr bool kHasDefaultFindOperation = meta::kIsDetected<HasDefaultFindOperation, T>;
86
87template <typename T>
88using HasInvalidDocumentsSkipped = decltype(T::kAreInvalidDocumentsSkipped);
89template <typename T>
90inline constexpr bool kHasInvalidDocumentsSkipped = meta::kIsDetected<HasInvalidDocumentsSkipped, T>;
91
92template <typename>
93struct ClassByMemberPointer {};
94template <typename T, typename C>
95struct ClassByMemberPointer<T C::*> {
96 using type = C;
97};
98template <typename CollectionPtr>
99using CollectionsType = typename ClassByMemberPointer<std::remove_cv_t<CollectionPtr>>::type;
100
101template <typename MongoCacheTraits>
102struct CheckTraits {
103 CheckTraits() {
104 if constexpr (kHasDefaultDeserializeObject<MongoCacheTraits>) {
105 static_assert(
106 std::is_same_v<std::decay_t<decltype(MongoCacheTraits::kUseDefaultDeserializeObject)>, bool>,
107 "Mongo cache traits must specify kUseDefaultDeserializeObject as "
108 "bool"
109 );
110 }
111 if constexpr (kHasDefaultFindOperation<MongoCacheTraits>) {
112 static_assert(
113 std::is_same_v<std::decay_t<decltype(MongoCacheTraits::kUseDefaultFindOperation)>, bool>,
114 "Mongo cache traits must specify kUseDefaultFindOperation as bool"
115 );
116 }
117 }
118
119 static_assert(kHasCollectionsField<MongoCacheTraits>, "Mongo cache traits must specify collections field");
120 static_assert(kHasKeyField<MongoCacheTraits>, "Mongo cache traits must specify key field");
121 static_assert(kHasValidDataType<MongoCacheTraits>, "Mongo cache traits must specify mapping data type");
122
123 static_assert(kHasSecondaryPreferred<MongoCacheTraits>, "Mongo cache traits must specify read preference");
124 static_assert(
125 std::is_same_v<std::decay_t<decltype(MongoCacheTraits::kIsSecondaryPreferred)>, bool>,
126 "Mongo cache traits must specify read preference of a bool type"
127 );
128
129 static_assert(kHasInvalidDocumentsSkipped<MongoCacheTraits>, "Mongo cache traits must specify validation policy");
130 static_assert(
131 std::is_same_v<std::decay_t<decltype(MongoCacheTraits::kAreInvalidDocumentsSkipped)>, bool>,
132 "Mongo cache traits must specify validation policy of a bool type"
133 );
134
135 static_assert(
136 kHasFindOperation<MongoCacheTraits> || kHasDefaultFindOperation<MongoCacheTraits>,
137 "Mongo cache traits must specify find operation"
138 );
139 static_assert(
140 !kHasFindOperation<MongoCacheTraits> || kHasCorrectFindOperation<MongoCacheTraits>,
141 "Mongo cache traits must specify find operation with correct "
142 "signature and return value type: "
143 "static storages::mongo::operations::Find GetFindOperation("
144 "cache::UpdateType type, "
145 "const std::chrono::system_clock::time_point& last_update, "
146 "const std::chrono::system_clock::time_point& now, "
147 "const std::chrono::system_clock::duration& correction)"
148 );
149
150 static_assert(
151 kHasDeserializeObject<MongoCacheTraits> || kHasDefaultDeserializeObject<MongoCacheTraits>,
152 "Mongo cache traits must specify deserialize object"
153 );
154 static_assert(
155 !kHasDeserializeObject<MongoCacheTraits> || kHasCorrectDeserializeObject<MongoCacheTraits>,
156 "Mongo cache traits must specify deserialize object with correct "
157 "signature and return value type: "
158 "static ObjectType DeserializeObject(const formats::bson::Document& "
159 "doc)"
160 );
161};
162
163} // namespace mongo_cache::impl
164
165USERVER_NAMESPACE_END