bson 4.15.0 → 5.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +94 -10
  3. data/Rakefile +68 -39
  4. data/ext/bson/bson-native.h +12 -4
  5. data/ext/bson/extconf.rb +8 -3
  6. data/ext/bson/init.c +11 -11
  7. data/ext/bson/read.c +39 -9
  8. data/ext/bson/util.c +171 -16
  9. data/ext/bson/write.c +34 -39
  10. data/lib/bson/active_support.rb +1 -0
  11. data/lib/bson/array.rb +58 -32
  12. data/lib/bson/big_decimal.rb +16 -6
  13. data/lib/bson/binary.rb +271 -129
  14. data/lib/bson/boolean.rb +1 -0
  15. data/lib/bson/code.rb +10 -12
  16. data/lib/bson/code_with_scope.rb +9 -11
  17. data/lib/bson/config.rb +1 -27
  18. data/lib/bson/date.rb +2 -1
  19. data/lib/bson/date_time.rb +2 -1
  20. data/lib/bson/db_pointer.rb +12 -13
  21. data/lib/bson/dbref.rb +11 -9
  22. data/lib/bson/decimal128/builder.rb +10 -9
  23. data/lib/bson/decimal128.rb +25 -111
  24. data/lib/bson/document.rb +1 -0
  25. data/lib/bson/environment.rb +1 -0
  26. data/lib/bson/error/bson_decode_error.rb +11 -0
  27. data/lib/bson/error/ext_json_parse_error.rb +11 -0
  28. data/lib/bson/error/illegal_key.rb +23 -0
  29. data/lib/bson/error/invalid_binary_type.rb +37 -0
  30. data/lib/bson/error/invalid_dbref_argument.rb +12 -0
  31. data/lib/bson/error/invalid_decimal128_argument.rb +25 -0
  32. data/lib/bson/error/invalid_decimal128_range.rb +27 -0
  33. data/lib/bson/error/invalid_decimal128_string.rb +26 -0
  34. data/lib/bson/error/invalid_key.rb +24 -0
  35. data/lib/bson/error/invalid_object_id.rb +11 -0
  36. data/lib/bson/error/invalid_regexp_pattern.rb +13 -0
  37. data/lib/bson/error/unrepresentable_precision.rb +19 -0
  38. data/lib/bson/error/unserializable_class.rb +13 -0
  39. data/lib/bson/error/unsupported_binary_subtype.rb +12 -0
  40. data/lib/bson/error/unsupported_type.rb +11 -0
  41. data/lib/bson/error.rb +16 -28
  42. data/lib/bson/ext_json.rb +2 -1
  43. data/lib/bson/false_class.rb +2 -1
  44. data/lib/bson/float.rb +3 -2
  45. data/lib/bson/hash.rb +128 -73
  46. data/lib/bson/int32.rb +17 -5
  47. data/lib/bson/int64.rb +17 -5
  48. data/lib/bson/integer.rb +4 -5
  49. data/lib/bson/json.rb +1 -0
  50. data/lib/bson/max_key.rb +8 -10
  51. data/lib/bson/min_key.rb +8 -10
  52. data/lib/bson/nil_class.rb +1 -0
  53. data/lib/bson/object.rb +7 -27
  54. data/lib/bson/object_id.rb +84 -120
  55. data/lib/bson/open_struct.rb +3 -2
  56. data/lib/bson/regexp.rb +36 -65
  57. data/lib/bson/registry.rb +2 -6
  58. data/lib/bson/specialized.rb +2 -1
  59. data/lib/bson/string.rb +4 -27
  60. data/lib/bson/symbol.rb +23 -20
  61. data/lib/bson/time.rb +3 -2
  62. data/lib/bson/time_with_zone.rb +13 -1
  63. data/lib/bson/timestamp.rb +3 -2
  64. data/lib/bson/true_class.rb +2 -1
  65. data/lib/bson/undefined.rb +15 -1
  66. data/lib/bson/version.rb +3 -1
  67. data/lib/bson.rb +3 -2
  68. data/spec/bson/array_spec.rb +19 -60
  69. data/spec/bson/big_decimal_spec.rb +16 -4
  70. data/spec/bson/binary_spec.rb +129 -81
  71. data/spec/bson/binary_uuid_spec.rb +1 -0
  72. data/spec/bson/boolean_spec.rb +1 -0
  73. data/spec/bson/byte_buffer_read_spec.rb +1 -0
  74. data/spec/bson/byte_buffer_spec.rb +1 -0
  75. data/spec/bson/byte_buffer_write_spec.rb +1 -0
  76. data/spec/bson/code_spec.rb +5 -3
  77. data/spec/bson/code_with_scope_spec.rb +5 -3
  78. data/spec/bson/config_spec.rb +1 -35
  79. data/spec/bson/date_spec.rb +1 -0
  80. data/spec/bson/date_time_spec.rb +1 -0
  81. data/spec/bson/dbref_legacy_spec.rb +20 -3
  82. data/spec/bson/dbref_spec.rb +9 -9
  83. data/spec/bson/decimal128_spec.rb +40 -20
  84. data/spec/bson/document_as_spec.rb +1 -0
  85. data/spec/bson/document_spec.rb +1 -1
  86. data/spec/bson/ext_json_parse_spec.rb +1 -0
  87. data/spec/bson/false_class_spec.rb +8 -0
  88. data/spec/bson/float_spec.rb +8 -3
  89. data/spec/bson/hash_as_spec.rb +1 -0
  90. data/spec/bson/hash_spec.rb +87 -75
  91. data/spec/bson/int32_spec.rb +21 -6
  92. data/spec/bson/int64_spec.rb +21 -6
  93. data/spec/bson/integer_spec.rb +45 -13
  94. data/spec/bson/json_spec.rb +1 -0
  95. data/spec/bson/max_key_spec.rb +5 -3
  96. data/spec/bson/min_key_spec.rb +5 -3
  97. data/spec/bson/nil_class_spec.rb +1 -0
  98. data/spec/bson/object_id_spec.rb +57 -4
  99. data/spec/bson/object_spec.rb +2 -1
  100. data/spec/bson/open_struct_spec.rb +14 -71
  101. data/spec/bson/raw_spec.rb +9 -15
  102. data/spec/bson/regexp_spec.rb +4 -3
  103. data/spec/bson/registry_spec.rb +2 -1
  104. data/spec/bson/string_spec.rb +13 -38
  105. data/spec/bson/symbol_raw_spec.rb +25 -0
  106. data/spec/bson/symbol_spec.rb +15 -18
  107. data/spec/bson/time_spec.rb +1 -0
  108. data/spec/bson/time_with_zone_spec.rb +1 -0
  109. data/spec/bson/timestamp_spec.rb +1 -0
  110. data/spec/bson/true_class_spec.rb +8 -0
  111. data/spec/bson/undefined_spec.rb +27 -0
  112. data/spec/bson_spec.rb +1 -0
  113. data/spec/runners/common_driver.rb +6 -5
  114. data/spec/runners/corpus.rb +6 -0
  115. data/spec/runners/corpus_legacy.rb +1 -0
  116. data/spec/spec_helper.rb +1 -0
  117. data/spec/spec_tests/common_driver_spec.rb +9 -4
  118. data/spec/spec_tests/corpus_legacy_spec.rb +1 -0
  119. data/spec/spec_tests/corpus_spec.rb +13 -3
  120. data/spec/spec_tests/data/corpus/binary.json +5 -0
  121. data/spec/spec_tests/data/corpus/code.json +13 -13
  122. data/spec/spec_tests/data/corpus/decimal128-4.json +48 -0
  123. data/spec/spec_tests/data/corpus/decimal128-6.json +12 -0
  124. data/spec/spec_tests/data/corpus/decimal128-7.json +4 -0
  125. data/spec/spec_tests/data/corpus/document.json +20 -0
  126. data/spec/spec_tests/data/corpus/symbol.json +7 -7
  127. data/spec/spec_tests/data/corpus/top.json +18 -3
  128. data/spec/support/shared_examples.rb +28 -5
  129. data/spec/support/spec_config.rb +1 -0
  130. data/spec/support/utils.rb +49 -1
  131. metadata +114 -164
  132. checksums.yaml.gz.sig +0 -0
  133. data/spec/shared/LICENSE +0 -20
  134. data/spec/shared/bin/get-mongodb-download-url +0 -17
  135. data/spec/shared/bin/s3-copy +0 -45
  136. data/spec/shared/bin/s3-upload +0 -69
  137. data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
  138. data/spec/shared/lib/mrss/cluster_config.rb +0 -231
  139. data/spec/shared/lib/mrss/constraints.rb +0 -386
  140. data/spec/shared/lib/mrss/docker_runner.rb +0 -271
  141. data/spec/shared/lib/mrss/event_subscriber.rb +0 -200
  142. data/spec/shared/lib/mrss/lite_constraints.rb +0 -191
  143. data/spec/shared/lib/mrss/server_version_registry.rb +0 -120
  144. data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
  145. data/spec/shared/lib/mrss/utils.rb +0 -15
  146. data/spec/shared/share/Dockerfile.erb +0 -338
  147. data/spec/shared/share/haproxy-1.conf +0 -16
  148. data/spec/shared/share/haproxy-2.conf +0 -17
  149. data/spec/shared/shlib/distro.sh +0 -74
  150. data/spec/shared/shlib/server.sh +0 -367
  151. data/spec/shared/shlib/set_env.sh +0 -131
  152. data.tar.gz.sig +0 -0
  153. metadata.gz.sig +0 -1
data/lib/bson/max_key.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ # rubocop:todo all
2
3
  # Copyright (C) 2009-2020 MongoDB Inc.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -51,21 +52,18 @@ module BSON
51
52
  GREATER
52
53
  end
53
54
 
54
- # Get the max key as JSON hash data.
55
+ # Return a representation of the object for use in
56
+ # application-level JSON serialization. Since BSON::MaxKey
57
+ # is used exclusively in BSON-related contexts, this
58
+ # method returns the canonical Extended JSON representation.
55
59
  #
56
- # @example Get the max key as a JSON hash.
57
- # max_key.as_json
58
- #
59
- # @return [ Hash ] The max key as a JSON hash.
60
- #
61
- # @since 2.0.0
62
- # @deprecated Use as_extended_json instead.
63
- def as_json(*args)
60
+ # @return [ Hash ] The extended json representation.
61
+ def as_json(*_args)
64
62
  as_extended_json
65
63
  end
66
64
 
67
65
  # Converts this object to a representation directly serializable to
68
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
66
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
69
67
  #
70
68
  # @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
71
69
  # (default is canonical extended JSON)
data/lib/bson/min_key.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ # rubocop:todo all
2
3
  # Copyright (C) 2009-2020 MongoDB Inc.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -51,21 +52,18 @@ module BSON
51
52
  LESSER
52
53
  end
53
54
 
54
- # Get the min key as JSON hash data.
55
+ # Return a representation of the object for use in
56
+ # application-level JSON serialization. Since BSON::MinKey
57
+ # is used exclusively in BSON-related contexts, this
58
+ # method returns the canonical Extended JSON representation.
55
59
  #
56
- # @example Get the min key as a JSON hash.
57
- # min_key.as_json
58
- #
59
- # @return [ Hash ] The min key as a JSON hash.
60
- #
61
- # @since 2.0.0
62
- # @deprecated Use as_extended_json instead.
63
- def as_json(*args)
60
+ # @return [ Hash ] The extended json representation.
61
+ def as_json(*_args)
64
62
  as_extended_json
65
63
  end
66
64
 
67
65
  # Converts this object to a representation directly serializable to
68
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
66
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
69
67
  #
70
68
  # @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
71
69
  # (default is canonical extended JSON)
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ # rubocop:todo all
2
3
  # Copyright (C) 2009-2020 MongoDB Inc.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
data/lib/bson/object.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ # rubocop:todo all
2
3
  # Copyright (C) 2009-2020 MongoDB Inc.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,13 +28,13 @@ module BSON
27
28
  # @example Convert the object to a BSON key.
28
29
  # object.to_bson_key
29
30
  #
30
- # @raise [ InvalidKey ] Always raises an exception.
31
+ # @raise [ BSON::Error::InvalidKey ] Always raises an exception.
31
32
  #
32
33
  # @see http://bsonspec.org/#/specification
33
34
  #
34
35
  # @since 2.2.4
35
- def to_bson_key(validating_keys = Config.validating_keys?)
36
- raise InvalidKey.new(self)
36
+ def to_bson_key
37
+ raise Error::InvalidKey.new(self)
37
38
  end
38
39
 
39
40
  # Converts the object to a normalized key in a BSON document.
@@ -61,7 +62,7 @@ module BSON
61
62
  end
62
63
 
63
64
  # Serializes this object to Extended JSON
64
- # (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
65
+ # (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
65
66
  #
66
67
  # Subclasses should override +as_extended_json+ rather than this method.
67
68
  #
@@ -74,38 +75,17 @@ module BSON
74
75
  end
75
76
 
76
77
  # Converts this object to a representation directly serializable to
77
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
78
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
78
79
  #
79
80
  # Subclasses should override this method to provide custom serialization
80
81
  # to Extended JSON.
81
82
  #
82
- # @option options [ true | false ] :relaxed Whether to produce relaxed
83
- # extended JSON representation.
84
- #
85
83
  # @return [ Object ] The extended json representation.
86
- def as_extended_json(**options)
84
+ def as_extended_json(**_options)
87
85
  self
88
86
  end
89
87
  end
90
88
 
91
- # Raised when trying to serialize an object into a key.
92
- #
93
- # @since 2.2.4
94
- class InvalidKey < RuntimeError
95
-
96
- # Instantiate the exception.
97
- #
98
- # @example Instantiate the exception.
99
- # BSON::Object::InvalidKey.new(object)
100
- #
101
- # @param [ Object ] object The object that was meant for the key.
102
- #
103
- # @since 2.2.4
104
- def initialize(object)
105
- super("#{object.class} instances are not allowed as keys in a BSON document.")
106
- end
107
- end
108
-
109
89
  # Enrich the core Object class with this module.
110
90
  #
111
91
  # @since 2.2.4
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright (C) 2009-2020 MongoDB Inc.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,12 +14,7 @@
13
14
  # See the License for the specific language governing permissions and
14
15
  # limitations under the License.
15
16
 
16
- require "digest/md5"
17
- require "socket"
18
- require "thread"
19
-
20
17
  module BSON
21
-
22
18
  # Represents object_id data.
23
19
  #
24
20
  # @see http://bsonspec.org/#/specification
@@ -45,9 +41,10 @@ module BSON
45
41
  # @since 2.0.0
46
42
  def ==(other)
47
43
  return false unless other.is_a?(ObjectId)
44
+
48
45
  generate_data == other.send(:generate_data)
49
46
  end
50
- alias :eql? :==
47
+ alias eql? ==
51
48
 
52
49
  # Check case equality on the object id.
53
50
  #
@@ -60,32 +57,29 @@ module BSON
60
57
  #
61
58
  # @since 2.0.0
62
59
  def ===(other)
63
- return to_str === other.to_str if other.respond_to?(:to_str)
60
+ return to_str == other.to_str if other.respond_to?(:to_str)
61
+
64
62
  super
65
63
  end
66
64
 
67
- # Return the object id as a JSON hash representation.
65
+ # Return a string representation of the object id for use in
66
+ # application-level JSON serialization. This method is intentionally
67
+ # different from #as_extended_json.
68
68
  #
69
- # @example Get the object id as JSON.
69
+ # @example Get the object id as a JSON-serializable object.
70
70
  # object_id.as_json
71
71
  #
72
- # @return [ Hash ] The object id as a JSON hash.
73
- #
74
- # @since 2.0.0
75
- # @deprecated Use as_extended_json instead.
76
- def as_json(*args)
77
- as_extended_json
72
+ # @return [ String ] The object id as a string.
73
+ def as_json(*_)
74
+ to_s
78
75
  end
79
76
 
80
77
  # Converts this object to a representation directly serializable to
81
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
82
- #
83
- # @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
84
- # (default is canonical extended JSON)
78
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
85
79
  #
86
80
  # @return [ Hash ] The extended json representation.
87
- def as_extended_json(**options)
88
- { "$oid" => to_s }
81
+ def as_extended_json(**_)
82
+ { '$oid' => to_s }
89
83
  end
90
84
 
91
85
  # Compare this object id with another object for use in sorting.
@@ -113,9 +107,9 @@ module BSON
113
107
  #
114
108
  # @since 2.0.0
115
109
  def generation_time
116
- ::Time.at(generate_data.unpack1("N")).utc
110
+ ::Time.at(generate_data.unpack1('N')).utc
117
111
  end
118
- alias :to_time :generation_time
112
+ alias to_time generation_time
119
113
 
120
114
  # Get the hash value for the object id.
121
115
  #
@@ -138,7 +132,7 @@ module BSON
138
132
  #
139
133
  # @since 2.0.0
140
134
  def inspect
141
- "BSON::ObjectId('#{to_s}')"
135
+ "BSON::ObjectId('#{self}')"
142
136
  end
143
137
 
144
138
  # Dump the raw bson when calling Marshal.dump.
@@ -182,7 +176,7 @@ module BSON
182
176
  # @see http://bsonspec.org/#/specification
183
177
  #
184
178
  # @since 2.0.0
185
- def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
179
+ def to_bson(buffer = ByteBuffer.new)
186
180
  buffer.put_bytes(generate_data)
187
181
  end
188
182
 
@@ -197,12 +191,46 @@ module BSON
197
191
  def to_s
198
192
  generate_data.to_hex_string.force_encoding(UTF8)
199
193
  end
200
- alias :to_str :to_s
194
+ alias to_str to_s
201
195
 
202
- # Raised when trying to create an object id with invalid data.
196
+ # Extract the process-specific part of the object id. This is used only
197
+ # internally, for testing, and should not be used elsewhere.
203
198
  #
204
- # @since 2.0.0
205
- class Invalid < RuntimeError; end
199
+ # @return [ String ] The process portion of the id.
200
+ #
201
+ # @api private
202
+ def _process_part
203
+ to_s[8, 10]
204
+ end
205
+
206
+ # Extract the counter-specific part of the object id. This is used only
207
+ # internally, for testing, and should not be used elsewhere.
208
+ #
209
+ # @return [ String ] The counter portion of the id.
210
+ #
211
+ # @api private
212
+ def _counter_part
213
+ to_s[18, 6]
214
+ end
215
+
216
+ # Extended by native code (see init.c, util.c, GeneratorExtension.java)
217
+ #
218
+ # @api private
219
+ #
220
+ # rubocop:disable Lint/EmptyClass
221
+ class Generator
222
+ end
223
+ # rubocop:enable Lint/EmptyClass
224
+
225
+ # We keep one global generator for object ids.
226
+ @@generator = Generator.new
227
+
228
+ # Accessor for querying the generator directly; used in testing.
229
+ #
230
+ # @api private
231
+ def self._generator
232
+ @@generator
233
+ end
206
234
 
207
235
  private
208
236
 
@@ -213,7 +241,10 @@ module BSON
213
241
 
214
242
  def generate_data
215
243
  repair if defined?(@data)
244
+
245
+ # rubocop:disable Naming/MemoizedInstanceVariableName
216
246
  @raw_data ||= @@generator.next_object_id
247
+ # rubocop:enable Naming/MemoizedInstanceVariableName
217
248
  end
218
249
 
219
250
  def repair
@@ -222,20 +253,18 @@ module BSON
222
253
  end
223
254
 
224
255
  class << self
225
-
226
256
  # Deserialize the object id from raw BSON bytes.
227
257
  #
228
258
  # @example Get the object id from BSON.
229
259
  # ObjectId.from_bson(bson)
230
260
  #
231
261
  # @param [ ByteBuffer ] buffer The byte buffer.
232
- #
233
- # @option options [ nil | :bson ] :mode Decoding mode to use.
262
+ # @param [ Hash ] _ An optional hash of keyword arguments (unused).
234
263
  #
235
264
  # @return [ BSON::ObjectId ] The object id.
236
265
  #
237
266
  # @since 2.0.0
238
- def from_bson(buffer, **options)
267
+ def from_bson(buffer, **_)
239
268
  from_data(buffer.get_bytes(12))
240
269
  end
241
270
 
@@ -262,16 +291,15 @@ module BSON
262
291
  #
263
292
  # @param [ String ] string The string to create the id from.
264
293
  #
265
- # @raise [ BSON::ObjectId::Invalid ] If the provided string is invalid.
294
+ # @raise [ BSON::Error::InvalidObjectId ] If the provided string is invalid.
266
295
  #
267
296
  # @return [ BSON::ObjectId ] The new object id.
268
297
  #
269
298
  # @since 2.0.0
270
299
  def from_string(string)
271
- unless legal?(string)
272
- raise Invalid.new("'#{string}' is an invalid ObjectId.")
273
- end
274
- from_data([ string ].pack("H*"))
300
+ raise Error::InvalidObjectId, "'#{string}' is an invalid ObjectId." unless legal?(string)
301
+
302
+ from_data([ string ].pack('H*'))
275
303
  end
276
304
 
277
305
  # Create a new object id from a time.
@@ -292,7 +320,7 @@ module BSON
292
320
  #
293
321
  # @since 2.0.0
294
322
  def from_time(time, options = {})
295
- from_data(options[:unique] ? @@generator.next_object_id(time.to_i) : [ time.to_i ].pack("Nx8"))
323
+ from_data(options[:unique] ? @@generator.next_object_id(time.to_i) : [ time.to_i ].pack('Nx8'))
296
324
  end
297
325
 
298
326
  # Determine if the provided string is a legal object id.
@@ -306,7 +334,7 @@ module BSON
306
334
  #
307
335
  # @since 2.0.0
308
336
  def legal?(string)
309
- string.to_s =~ /\A[0-9a-f]{24}\z/i ? true : false
337
+ (string.to_s =~ /\A[0-9a-f]{24}\z/i) ? true : false
310
338
  end
311
339
 
312
340
  # Executes the provided block only if the size of the provided object is
@@ -317,100 +345,36 @@ module BSON
317
345
  #
318
346
  # @param [ String, Array ] object The object to repair.
319
347
  #
320
- # @raise [ Invalid ] If the array is not 12 elements.
348
+ # @raise [ BSON::Error::InvalidObjectId ] If the array is not 12 elements.
321
349
  #
322
350
  # @return [ String ] The result of the block.
323
351
  #
324
352
  # @since 2.0.0
325
353
  def repair(object)
326
- if object.size == 12
327
- block_given? ? yield(object) : object
328
- else
329
- raise Invalid.new("#{object.inspect} is not a valid object id.")
330
- end
331
- end
332
- end
333
-
334
- # Inner class that encapsulates the behaviour of actually generating each
335
- # part of the ObjectId.
336
- #
337
- # @api private
338
- #
339
- # @since 2.0.0
340
- class Generator
341
-
342
- # @!attribute machine_id
343
- # @return [ String ] The unique machine id.
344
- # @since 2.0.0
345
- attr_reader :machine_id
354
+ raise Error::InvalidObjectId, "#{object.inspect} is not a valid object id." if object.size != 12
346
355
 
347
- # Instantiate the new object id generator. Will set the machine id once
348
- # on the initial instantiation.
349
- #
350
- # @example Instantiate the generator.
351
- # BSON::ObjectId::Generator.new
352
- #
353
- # @since 2.0.0
354
- def initialize
355
- @counter = rand(0x1000000)
356
- @machine_id = Digest::MD5.digest(Socket.gethostname).unpack1("N")
357
- @mutex = Mutex.new
356
+ block_given? ? yield(object) : object
358
357
  end
359
358
 
360
- # Return object id data based on the current time, incrementing the
361
- # object id counter. Will use the provided time if not nil.
362
- #
363
- # @example Get the next object id data.
364
- # generator.next_object_id
365
- #
366
- # @param [ Time ] time The optional time to generate with.
367
- #
368
- # @return [ String ] The raw object id bytes.
369
- #
370
- # @since 2.0.0
371
- def next_object_id(time = nil)
372
- @mutex.lock
373
- begin
374
- count = @counter = (@counter + 1) % 0xFFFFFF
375
- ensure
376
- @mutex.unlock rescue nil
377
- end
378
- generate(time || ::Time.new.to_i, count)
379
- end
359
+ # The largest numeric value that can be converted to an integer by MRI's
360
+ # NUM2UINT. Further, the spec dictates that the time component of an
361
+ # ObjectID must be no more than 4 bytes long, so the spec itself is
362
+ # constrained in this regard.
363
+ MAX_INTEGER = 2 ** 32
380
364
 
381
- # Generate object id data for a given time using the provided counter.
382
- #
383
- # @example Generate the object id bytes.
384
- # generator.generate(time)
365
+ # Returns an integer timestamp (seconds since the Epoch). Primarily used
366
+ # by the generator to produce object ids.
385
367
  #
386
- # @param [ Integer ] time The time since epoch in seconds.
387
- # @param [ Integer ] counter The optional counter.
368
+ # @note This value is guaranteed to be no more than 4 bytes in length. A
369
+ # time value far enough in the future to require a larger integer than
370
+ # 4 bytes will be truncated to 4 bytes.
388
371
  #
389
- # @return [ String ] The raw object id bytes.
390
- #
391
- # @since 2.0.0
392
- def generate(time, counter = 0)
393
- [ time, machine_id, process_id, counter << 8 ].pack("N NX lXX NX")
394
- end
395
-
396
- private
397
-
398
- if Environment.jruby?
399
- def process_id
400
- "#{Process.pid}#{Thread.current.object_id}".hash % 0xFFFF
401
- end
402
- else
403
- def process_id
404
- Process.pid % 0xFFFF
405
- end
372
+ # @return [ Integer ] the number of seconds since the Epoch.
373
+ def timestamp
374
+ ::Time.now.to_i % MAX_INTEGER
406
375
  end
407
376
  end
408
377
 
409
- # We keep one global generator for object ids.
410
- #
411
- # @since 2.0.0
412
- @@generator = Generator.new
413
-
414
378
  # Register this type when the module is loaded.
415
379
  #
416
380
  # @since 2.0.0
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ # rubocop:todo all
2
3
  # Copyright (C) 2016-2020 MongoDB Inc.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -33,12 +34,12 @@ module BSON
33
34
  # @see http://bsonspec.org/#/specification
34
35
  #
35
36
  # @since 4.2.0
36
- def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
37
+ def to_bson(buffer = ByteBuffer.new)
37
38
  if Environment.ruby_1_9?
38
39
  marshal_dump.dup
39
40
  else
40
41
  to_h
41
- end.to_bson(buffer, validating_keys)
42
+ end.to_bson(buffer)
42
43
  end
43
44
 
44
45
  # The BSON type for OpenStruct objects is the Hash type of 0x03.