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
89private:
90 friend struct std::hash<Oid>;
91
92 bson_oid_t oid_;
93};
94
95logging::LogHelper& operator<<(logging::LogHelper& lh, const Oid& value);
96
97/// BSON Binary
98class Binary {
99public:
100 /// Constructor from a string storage
101 explicit Binary(std::string data)
102 : data_(std::move(data))
103 {}
104
105 /// @name Raw data access
106 /// @{
107 const std::string& ToString() const& { return data_; }
108 std::string&& ToString() && { return std::move(data_); }
109
110 const uint8_t* Data() const { return reinterpret_cast<const uint8_t*>(data_.data()); }
111 size_t Size() const { return data_.size(); }
112 /// @}
113
114 bool operator==(const Binary& rhs) const { return data_ == rhs.data_; }
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
121private:
122 friend struct std::hash<Binary>;
123
124 std::string data_;
125};
126
127/// @brief BSON Decimal128
128/// @see
129/// https://github.com/mongodb/specifications/blob/master/source/bson-decimal128/decimal128.rst
131public:
132 /// Constructor from a string form
133 explicit Decimal128(const std::string& value);
134
135 /// @cond
136 /// Constructor from native type
137 /* implicit */ Decimal128(const bson_decimal128_t&);
138 /// @endcond
139
140 /// Returns string form
141 std::string ToString() const;
142
143 /// Returns an infinite value
145
146 /// Returns a not-a-number value
147 static Decimal128 NaN();
148
149 /// @cond
150 /// Native type access, internal use only
151 const bson_decimal128_t* GetNative() const;
152 /// @endcond
153
154 bool operator==(const Decimal128&) const;
155 bool operator!=(const Decimal128&) const;
156
157private:
158 bson_decimal128_t decimal_;
159};
160
161/// BSON MinKey
162class MinKey {};
163
164/// BSON MaxKey
165class MaxKey {};
166
167/// @brief BSON Timestamp
168/// @warning Do not use this type for time point representation!
169/// It is very limited and intended for internal MongoDB use.
171public:
172 /// @brief Creates an empty timestamp
173 /// @note MongoDB only replaces empty timestamps in top-level fields.
175
176 /// Creates a timestamp with specified values
177 Timestamp(uint32_t timestamp, uint32_t increment);
178
179 /// Returns stored unix timestamp
180 time_t GetTimestamp() const;
181
182 /// Returns stored increment
183 uint32_t GetIncrement() const;
184
185 /// Returns packed 64-bit timestamp value
186 uint64_t Pack() const;
187
188 /// Restores a timestamp from the packed form
189 static Timestamp Unpack(uint64_t);
190
191 bool operator==(const Timestamp&) const;
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
198private:
199 uint32_t timestamp_{0};
200 uint32_t increment_{0};
201};
202
203} // namespace formats::bson
204
205USERVER_NAMESPACE_END
206
207namespace std {
208
209template <>
210struct hash<USERVER_NAMESPACE::formats::bson::Oid> {
211 size_t operator()(const USERVER_NAMESPACE::formats::bson::Oid&) const;
212};
213
214template <>
215struct hash<USERVER_NAMESPACE::formats::bson::Binary> {
216 size_t operator()(const USERVER_NAMESPACE::formats::bson::Binary& binary) const {
217 return hash<string>()(binary.data_);
218 }
219};
220
221template <>
222struct hash<USERVER_NAMESPACE::formats::bson::Timestamp> {
223 size_t operator()(const USERVER_NAMESPACE::formats::bson::Timestamp& timestamp) const;
224};
225
226} // namespace std
227
228template <>
229struct fmt::formatter<USERVER_NAMESPACE::formats::bson::Oid> {
230 constexpr static auto parse(format_parse_context& ctx) { return ctx.begin(); }
231
232 template <typename FormatContext>
233 auto format(USERVER_NAMESPACE::formats::bson::Oid oid, FormatContext& ctx) USERVER_FMT_CONST {
234 return fmt::format_to(ctx.out(), "{}", oid.ToString());
235 }
236};