userver: userver/formats/bson/types.hpp Source File
Loading...
Searching...
No Matches
types.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/formats/bson/types.hpp
4/// @brief BSON-specific types
5
6#include <chrono>
7#include <cstdint>
8#include <functional>
9#include <memory>
10#include <string>
11#include <unordered_map>
12#include <vector>
13
14#include <bson/bson.h>
15#include <fmt/core.h>
16
17#include <userver/formats/common/path.hpp>
18#include <userver/logging/log_helper_fwd.hpp>
19#include <userver/utils/fmt_compat.hpp>
20
21USERVER_NAMESPACE_BEGIN
22
23namespace formats::bson {
24namespace impl {
25// https://jira.mongodb.org/browse/CDRIVER-3378
26#pragma GCC diagnostic push
27#pragma GCC diagnostic ignored "-Wignored-attributes"
28using BsonHolder = std::shared_ptr<const bson_t>;
29#pragma GCC diagnostic pop
30
31class ValueImpl;
32using ValueImplPtr = std::shared_ptr<ValueImpl>;
33
34using ParsedArray = std::vector<ValueImplPtr>;
35using ParsedDocument = std::unordered_map<std::string, ValueImplPtr>;
36} // namespace impl
37
38using formats::common::Path;
39
40inline constexpr auto kNull = nullptr;
41
42/// BSON ObjectId
43class Oid {
44public:
45 /// Generates a new id
46 Oid();
47
48 /// Constructor from hex-encoded form, zero terminator is not required
49 explicit Oid(std::string_view hex_encoded);
50
51 /// Creates a minimal Oid with specified time point up to a second precision
52 ///
53 /// @throws formats::bson::BsonException if `time` is too big to be stored in
54 /// ObjectId without narrowing.
55 static Oid MakeMinimalFor(std::chrono::system_clock::time_point time);
56
57 /// @cond
58 /// Constructor from native type
59 /* implicit */ Oid(const bson_oid_t&);
60 /// @endcond
61
62 /// Returns hex-encoded value
63 std::string ToString() const;
64
65 /// @name Raw value access
66 /// @{
67 const uint8_t* Data() const;
68
69 constexpr static size_t Size() { return 12; }
70 /// @}
71
72 /// Returns stored unix timestamp
73 time_t GetTimestamp() const;
74
75 /// Returns stored time point
76 std::chrono::system_clock::time_point GetTimePoint() const;
77
78 /// @cond
79 /// Native type access, internal use only
80 const bson_oid_t* GetNative() const;
81 /// @endcond
82
83 bool operator==(const Oid&) const;
84 bool operator!=(const Oid&) const;
85 bool operator<(const Oid&) const;
86 bool operator>(const Oid&) const;
87 bool operator<=(const Oid&) const;
88 bool operator>=(const Oid&) const;
89
90private:
91 friend struct std::hash<Oid>;
92
93 bson_oid_t oid_;
94};
95
96logging::LogHelper& operator<<(logging::LogHelper& lh, const Oid& value);
97
98/// BSON Binary
99class Binary {
100public:
101 /// Constructor from a string storage
102 explicit Binary(std::string data)
103 : data_(std::move(data))
104 {}
105
106 /// @name Raw data access
107 /// @{
108 const std::string& ToString() const& { return data_; }
109 std::string&& ToString() && { return std::move(data_); }
110
111 const uint8_t* Data() const { return reinterpret_cast<const uint8_t*>(data_.data()); }
112 size_t Size() const { return data_.size(); }
113 /// @}
114
115 bool operator==(const Binary& rhs) const { return data_ == rhs.data_; }
116 bool operator!=(const Binary& rhs) const { return data_ != rhs.data_; }
117 bool operator<(const Binary& rhs) const { return data_ < rhs.data_; }
118 bool operator>(const Binary& rhs) const { return data_ > rhs.data_; }
119 bool operator<=(const Binary& rhs) const { return data_ <= rhs.data_; }
120 bool operator>=(const Binary& rhs) const { return data_ >= rhs.data_; }
121
122private:
123 friend struct std::hash<Binary>;
124
125 std::string data_;
126};
127
128/// @brief BSON Decimal128
129/// @see
130/// https://github.com/mongodb/specifications/blob/master/source/bson-decimal128/decimal128.rst
132public:
133 /// Constructor from a string form
134 explicit Decimal128(const std::string& value);
135
136 /// @cond
137 /// Constructor from native type
138 /* implicit */ Decimal128(const bson_decimal128_t&);
139 /// @endcond
140
141 /// Returns string form
142 std::string ToString() const;
143
144 /// Returns an infinite value
146
147 /// Returns a not-a-number value
148 static Decimal128 NaN();
149
150 /// @cond
151 /// Native type access, internal use only
152 const bson_decimal128_t* GetNative() const;
153 /// @endcond
154
155 bool operator==(const Decimal128&) const;
156 bool operator!=(const Decimal128&) const;
157
158private:
159 bson_decimal128_t decimal_;
160};
161
162/// BSON MinKey
163class MinKey {};
164
165/// BSON MaxKey
166class MaxKey {};
167
168/// @brief BSON Timestamp
169/// @warning Do not use this type for time point representation!
170/// It is very limited and intended for internal MongoDB use.
172public:
173 /// @brief Creates an empty timestamp
174 /// @note MongoDB only replaces empty timestamps in top-level fields.
176
177 /// Creates a timestamp with specified values
178 Timestamp(uint32_t timestamp, uint32_t increment);
179
180 /// Returns stored unix timestamp
181 time_t GetTimestamp() const;
182
183 /// Returns stored increment
184 uint32_t GetIncrement() const;
185
186 /// Returns packed 64-bit timestamp value
187 uint64_t Pack() const;
188
189 /// Restores a timestamp from the packed form
190 static Timestamp Unpack(uint64_t);
191
192 bool operator==(const Timestamp&) const;
193 bool operator!=(const Timestamp&) const;
194 bool operator<(const Timestamp&) const;
195 bool operator>(const Timestamp&) const;
196 bool operator<=(const Timestamp&) const;
197 bool operator>=(const Timestamp&) const;
198
199private:
200 uint32_t timestamp_{0};
201 uint32_t increment_{0};
202};
203
204} // namespace formats::bson
205
206USERVER_NAMESPACE_END
207
208namespace std {
209
210template <>
211struct hash<USERVER_NAMESPACE::formats::bson::Oid> {
212 size_t operator()(const USERVER_NAMESPACE::formats::bson::Oid&) const;
213};
214
215template <>
216struct hash<USERVER_NAMESPACE::formats::bson::Binary> {
217 size_t operator()(const USERVER_NAMESPACE::formats::bson::Binary& binary) const {
218 return hash<string>()(binary.data_);
219 }
220};
221
222template <>
223struct hash<USERVER_NAMESPACE::formats::bson::Timestamp> {
224 size_t operator()(const USERVER_NAMESPACE::formats::bson::Timestamp& timestamp) const;
225};
226
227} // namespace std
228
229template <>
230struct fmt::formatter<USERVER_NAMESPACE::formats::bson::Oid> {
231 constexpr static auto parse(format_parse_context& ctx) { return ctx.begin(); }
232
233 template <typename FormatContext>
234 auto format(USERVER_NAMESPACE::formats::bson::Oid oid, FormatContext& ctx) USERVER_FMT_CONST {
235 return fmt::format_to(ctx.out(), "{}", oid.ToString());
236 }
237};