bson 4.8.0 → 4.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c37081fa823c2700f07a23ca6ecbec6fc67cffbf7915b4a21e59940b332b678d
4
- data.tar.gz: 16d483a311c4252f4ef1463be2f86240450b82294a972d8bb5bb2bb332fd7b17
3
+ metadata.gz: ef5a31f0820c55727982451d554e05971480a6df19a3a959eea4731326193614
4
+ data.tar.gz: 8928dec44431fa67fba6f5b95a469ee5e8c8d17d12880ac5c35aa556acff697a
5
5
  SHA512:
6
- metadata.gz: 1618b74348d155c904b2f24739d7b9403bc0b1c23e67cc6ce89a92ac19070dd5965dc1fccc6353c2eefb82993bf5fec30702bccaaf6bb8171777421253832cce
7
- data.tar.gz: 1362710c9b36348437bf266a52c18347c1228ddd92231b520e6b068b1742f42895c2108a64cdff2487c5b874c12e3af5ce4d4435c00cebad942b83f1ea9e17ab
6
+ metadata.gz: 48e4afe1f4da2dd9161e326f05c9c3dcf0f287845eb46fb3eebfe08e761df0e73d36bf0745867fca70ace7345d8a243826da9a0f89f9b3c4a28e903b74817949
7
+ data.tar.gz: b40043516efec6952d2f83ffa84183ed4e7e23a545ed9b51e12729d65f6a944131468ea4278dccf4cdde5e6ec9f859bc9cad04aeae167f9a143ebe62731df9e3
@@ -1,2 +1,4 @@
1
- �}
2
- O��t���9a���2)����=%Zf{ms 3VeBL)¡ocrpe��r��@�K�~�
1
+ j4�}��=#��/M��%0L=�_J��WuZ��!7��/�2�3���D3�-�2�\)f$�uDr�2����Ѱ�����q?6���@
2
+ 齴F �|��ZI�|^���漴�g�&�}LtRKQ��8����R��ʙɠI�OU�(��B�خ�RF�K�,neU ��Jz)��
3
+ �uYƼ�FQ�4�>�s����R+�1��b9�0<l����#H�6
4
+ ��Q���'{��}F��+
data.tar.gz.sig CHANGED
Binary file
@@ -256,7 +256,8 @@ module BSON
256
256
  unless value.keys.sort == %w($numberLong)
257
257
  raise Error::ExtJSONParseError, "Invalid value for $date: #{value}"
258
258
  end
259
- ::Time.at(value.values.first.to_i.to_f / 1000)
259
+ sec, msec = value.values.first.to_i.divmod(1000)
260
+ ::Time.at(sec, msec*1000)
260
261
  else
261
262
  raise Error::ExtJSONParseError, "Invalid value for $date: #{value}"
262
263
  end
@@ -112,7 +112,13 @@ module BSON
112
112
  while (type = buffer.get_byte) != NULL_BYTE
113
113
  field = buffer.get_cstring
114
114
  cls = BSON::Registry.get(type, field)
115
- value = cls.from_bson(buffer, **options)
115
+ value = if options.empty?
116
+ # Compatibility with the older Ruby driver versions which define
117
+ # a DBRef class with from_bson accepting a single argument.
118
+ cls.from_bson(buffer)
119
+ else
120
+ cls.from_bson(buffer, **options)
121
+ end
116
122
  hash.store(field, value)
117
123
  end
118
124
  hash
@@ -17,6 +17,20 @@ module BSON
17
17
  # Injects behaviour for encoding and decoding time values to
18
18
  # and from raw bytes as specified by the BSON spec.
19
19
  #
20
+ # @note
21
+ # Ruby time can have nanosecond precision:
22
+ # +Time.utc(2020, 1, 1, 0, 0, 0, 999_999_999/1000r)+
23
+ # +Time#usec+ returns the number of microseconds in the time, and
24
+ # if the time has nanosecond precision the sub-microsecond part is
25
+ # truncated (the value is floored to the nearest millisecond).
26
+ # MongoDB only supports millisecond precision; we truncate the
27
+ # sub-millisecond part of microseconds (floor to the nearest millisecond).
28
+ # Note that if a time is constructed from a floating point value,
29
+ # the microsecond value may round to the starting floating point value
30
+ # but due to flooring, the time after serialization may end up to
31
+ # be different than the starting floating point value.
32
+ # It is recommended that time calculations use integer math only.
33
+ #
20
34
  # @see http://bsonspec.org/#/specification
21
35
  #
22
36
  # @since 2.0.0
@@ -29,6 +43,8 @@ module BSON
29
43
 
30
44
  # Get the time as encoded BSON.
31
45
  #
46
+ # @note The time is floored to the nearest millisecond.
47
+ #
32
48
  # @example Get the time as encoded BSON.
33
49
  # Time.new(2012, 1, 1, 0, 0, 0).to_bson
34
50
  #
@@ -38,15 +54,15 @@ module BSON
38
54
  #
39
55
  # @since 2.0.0
40
56
  def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
41
- # A previous version of this method used the following implementation:
42
- # buffer.put_int64((to_i * 1000) + (usec / 1000))
43
- # Turns out, usec returned incorrect value - 999 for 1 millisecond.
44
- buffer.put_int64((to_f * 1000).round)
57
+ value = _bson_to_i * 1000 + usec.divmod(1000).first
58
+ buffer.put_int64(value)
45
59
  end
46
60
 
47
61
  # Converts this object to a representation directly serializable to
48
62
  # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
49
63
  #
64
+ # @note The time is floored to the nearest millisecond.
65
+ #
50
66
  # @option options [ true | false ] :relaxed Whether to produce relaxed
51
67
  # extended JSON representation.
52
68
  #
@@ -55,12 +71,30 @@ module BSON
55
71
  utc_time = utc
56
72
  if options[:mode] == :relaxed && (1970..9999).include?(utc_time.year)
57
73
  if utc_time.usec != 0
74
+ if utc_time.respond_to?(:floor)
75
+ # Ruby 2.7+
76
+ utc_time = utc_time.floor(3)
77
+ else
78
+ utc_time -= utc_time.usec.divmod(1000).last.to_r / 1000000
79
+ end
58
80
  {'$date' => utc_time.strftime('%Y-%m-%dT%H:%M:%S.%LZ')}
59
81
  else
60
82
  {'$date' => utc_time.strftime('%Y-%m-%dT%H:%M:%SZ')}
61
83
  end
62
84
  else
63
- {'$date' => {'$numberLong' => (utc_time.to_f * 1000).round.to_s}}
85
+ sec = utc_time._bson_to_i
86
+ msec = utc_time.usec.divmod(1000).first
87
+ {'$date' => {'$numberLong' => (sec * 1000 + msec).to_s}}
88
+ end
89
+ end
90
+
91
+ def _bson_to_i
92
+ # Workaround for JRuby's #to_i rounding negative timestamps up
93
+ # rather than down (https://github.com/jruby/jruby/issues/6104)
94
+ if BSON::Environment.jruby?
95
+ (self - usec.to_r/1000000).to_i
96
+ else
97
+ to_i
64
98
  end
65
99
  end
66
100
 
@@ -13,5 +13,5 @@
13
13
  # limitations under the License.
14
14
 
15
15
  module BSON
16
- VERSION = "4.8.0".freeze
16
+ VERSION = "4.8.1".freeze
17
17
  end
@@ -43,7 +43,7 @@ describe Time do
43
43
  end
44
44
  end
45
45
 
46
- context "when the time is pre epoch" do
46
+ context "when the time precedes epoch" do
47
47
 
48
48
  let(:obj) { Time.utc(1969, 1, 1, 0, 0, 0) }
49
49
  let(:bson) { [ (obj.to_f * 1000).to_i ].pack(BSON::Int64::PACK) }
@@ -51,5 +51,208 @@ describe Time do
51
51
  it_behaves_like "a serializable bson element"
52
52
  it_behaves_like "a deserializable bson element"
53
53
  end
54
+
55
+ context 'when value has sub-millisecond precision' do
56
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999) }
57
+
58
+ let(:expected_round_tripped_obj) do
59
+ Time.utc(2012, 1, 1, 0, 0, 0, 999_000)
60
+ end
61
+
62
+ let(:round_tripped_obj) do
63
+ Time.from_bson(obj.to_bson)
64
+ end
65
+
66
+ it 'truncates to milliseconds when round-tripping' do
67
+ round_tripped_obj.should == expected_round_tripped_obj
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#as_extended_json' do
73
+
74
+ context 'canonical mode' do
75
+ context 'when value has sub-millisecond precision' do
76
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999) }
77
+
78
+ let(:expected_serialization) do
79
+ {'$date' => {'$numberLong' => '1325376000999'}}
80
+ end
81
+
82
+ let(:serialization) do
83
+ obj.as_extended_json
84
+ end
85
+
86
+ shared_examples_for 'truncates to milliseconds when serializing' do
87
+ it 'truncates to milliseconds when serializing' do
88
+ serialization.should == expected_serialization
89
+ end
90
+ end
91
+
92
+ it_behaves_like 'truncates to milliseconds when serializing'
93
+
94
+ context 'when value has sub-microsecond precision' do
95
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999_999/1000r) }
96
+
97
+ it_behaves_like 'truncates to milliseconds when serializing'
98
+ end
99
+
100
+ context "when the time precedes epoch" do
101
+ let(:obj) { Time.utc(1960, 1, 1, 0, 0, 0, 999_999) }
102
+
103
+ let(:expected_serialization) do
104
+ {'$date' => {'$numberLong' => '-315619199001'}}
105
+ end
106
+
107
+ it_behaves_like 'truncates to milliseconds when serializing'
108
+ end
109
+ end
110
+ end
111
+
112
+ context 'relaxed mode' do
113
+ context 'when value has sub-millisecond precision' do
114
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999) }
115
+
116
+ let(:expected_serialization) do
117
+ {'$date' => '2012-01-01T00:00:00.999Z'}
118
+ end
119
+
120
+ let(:serialization) do
121
+ obj.as_extended_json(mode: :relaxed)
122
+ end
123
+
124
+ shared_examples_for 'truncates to milliseconds when serializing' do
125
+ it 'truncates to milliseconds when serializing' do
126
+ serialization.should == expected_serialization
127
+ end
128
+ end
129
+
130
+ it_behaves_like 'truncates to milliseconds when serializing'
131
+
132
+ context 'when value has sub-microsecond precision' do
133
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999_999/1000r) }
134
+
135
+ it_behaves_like 'truncates to milliseconds when serializing'
136
+ end
137
+
138
+ context "when the time precedes epoch" do
139
+ let(:obj) { Time.utc(1960, 1, 1, 0, 0, 0, 999_999) }
140
+
141
+ let(:expected_serialization) do
142
+ {'$date' => {'$numberLong' => '-315619199001'}}
143
+ end
144
+
145
+ it_behaves_like 'truncates to milliseconds when serializing'
146
+ end
147
+ end
148
+ end
149
+ end
150
+
151
+ describe '#to_extended_json' do
152
+
153
+ context 'canonical mode' do
154
+ context 'when value has sub-millisecond precision' do
155
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999) }
156
+
157
+ let(:expected_serialization) do
158
+ %q`{"$date":{"$numberLong":"1325376000999"}}`
159
+ end
160
+
161
+ let(:serialization) do
162
+ obj.to_extended_json
163
+ end
164
+
165
+ shared_examples_for 'truncates to milliseconds when serializing' do
166
+ it 'truncates to milliseconds when serializing' do
167
+ serialization.should == expected_serialization
168
+ end
169
+ end
170
+
171
+ it_behaves_like 'truncates to milliseconds when serializing'
172
+
173
+ context 'when value has sub-microsecond precision' do
174
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999_999/1000r) }
175
+
176
+ it_behaves_like 'truncates to milliseconds when serializing'
177
+ end
178
+
179
+ context "when the time precedes epoch" do
180
+ let(:obj) { Time.utc(1960, 1, 1, 0, 0, 0, 999_999) }
181
+
182
+ let(:expected_serialization) do
183
+ %q`{"$date":{"$numberLong":"-315619199001"}}`
184
+ end
185
+
186
+ it_behaves_like 'truncates to milliseconds when serializing'
187
+ end
188
+ end
189
+ end
190
+
191
+ context 'relaxed mode' do
192
+ context 'when value has sub-millisecond precision' do
193
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999) }
194
+
195
+ let(:expected_serialization) do
196
+ %q`{"$date":"2012-01-01T00:00:00.999Z"}`
197
+ end
198
+
199
+ let(:serialization) do
200
+ obj.to_extended_json(mode: :relaxed)
201
+ end
202
+
203
+ shared_examples_for 'truncates to milliseconds when serializing' do
204
+ it 'truncates to milliseconds when serializing' do
205
+ serialization.should == expected_serialization
206
+ end
207
+ end
208
+
209
+ it_behaves_like 'truncates to milliseconds when serializing'
210
+
211
+ context 'when value has sub-microsecond precision' do
212
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999_999/1000r) }
213
+
214
+ it_behaves_like 'truncates to milliseconds when serializing'
215
+ end
216
+ end
217
+ end
218
+ end
219
+
220
+ describe '#to_json' do
221
+
222
+ context 'when value has sub-millisecond precision' do
223
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999) }
224
+
225
+ let(:expected_serialization) do
226
+ %q`"2012-01-01 00:00:00 UTC"`
227
+ end
228
+
229
+ let(:serialization) do
230
+ obj.to_json
231
+ end
232
+
233
+ shared_examples_for 'truncates to milliseconds when serializing' do
234
+ it 'truncates to milliseconds when serializing' do
235
+ serialization.should == expected_serialization
236
+ end
237
+ end
238
+
239
+ it_behaves_like 'truncates to milliseconds when serializing'
240
+
241
+ context 'when value has sub-microsecond precision' do
242
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999_999/1000r) }
243
+
244
+ it_behaves_like 'truncates to milliseconds when serializing'
245
+ end
246
+
247
+ context "when the time precedes epoch" do
248
+ let(:obj) { Time.utc(1960, 1, 1, 0, 0, 0, 999_999) }
249
+
250
+ let(:expected_serialization) do
251
+ %q`"1960-01-01 00:00:00 UTC"`
252
+ end
253
+
254
+ it_behaves_like 'truncates to milliseconds when serializing'
255
+ end
256
+ end
54
257
  end
55
258
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bson
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.8.0
4
+ version: 4.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Brock
@@ -33,7 +33,7 @@ cert_chain:
33
33
  gpvfPNWMwyBDlHaNS3GfO6cRRxBOvEG05GUCsvtTY4Bpe8yjE64wg1ymb47LMOnv
34
34
  Qb1lGORmf/opg45mluKUYl7pQNZHD0d3
35
35
  -----END CERTIFICATE-----
36
- date: 2020-02-27 00:00:00.000000000 Z
36
+ date: 2020-03-03 00:00:00.000000000 Z
37
37
  dependencies: []
38
38
  description: A fully featured BSON specification implementation in Ruby
39
39
  email:
metadata.gz.sig CHANGED
Binary file