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