bson 4.7.1 → 4.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +2 -1
  4. data/README.md +6 -2
  5. data/ext/bson/bson-endian.h +1 -1
  6. data/ext/bson/bson-native.h +15 -5
  7. data/ext/bson/bytebuf.c +1 -1
  8. data/ext/bson/endian.c +1 -1
  9. data/ext/bson/init.c +26 -3
  10. data/ext/bson/read.c +127 -33
  11. data/ext/bson/util.c +41 -1
  12. data/ext/bson/write.c +18 -14
  13. data/lib/bson.rb +4 -1
  14. data/lib/bson/active_support.rb +1 -1
  15. data/lib/bson/array.rb +34 -5
  16. data/lib/bson/binary.rb +42 -4
  17. data/lib/bson/boolean.rb +12 -3
  18. data/lib/bson/code.rb +16 -2
  19. data/lib/bson/code_with_scope.rb +32 -5
  20. data/lib/bson/config.rb +1 -1
  21. data/lib/bson/date.rb +1 -1
  22. data/lib/bson/date_time.rb +1 -1
  23. data/lib/bson/db_pointer.rb +110 -0
  24. data/lib/bson/decimal128.rb +16 -2
  25. data/lib/bson/decimal128/builder.rb +1 -1
  26. data/lib/bson/document.rb +1 -1
  27. data/lib/bson/environment.rb +2 -1
  28. data/lib/bson/error.rb +21 -0
  29. data/lib/bson/ext_json.rb +375 -0
  30. data/lib/bson/false_class.rb +1 -1
  31. data/lib/bson/float.rb +48 -2
  32. data/lib/bson/hash.rb +36 -5
  33. data/lib/bson/int32.rb +22 -2
  34. data/lib/bson/int64.rb +29 -4
  35. data/lib/bson/integer.rb +35 -1
  36. data/lib/bson/json.rb +1 -1
  37. data/lib/bson/max_key.rb +13 -1
  38. data/lib/bson/min_key.rb +13 -1
  39. data/lib/bson/nil_class.rb +4 -2
  40. data/lib/bson/object.rb +28 -1
  41. data/lib/bson/object_id.rb +16 -2
  42. data/lib/bson/open_struct.rb +1 -1
  43. data/lib/bson/regexp.rb +20 -3
  44. data/lib/bson/registry.rb +1 -1
  45. data/lib/bson/specialized.rb +4 -2
  46. data/lib/bson/string.rb +4 -2
  47. data/lib/bson/symbol.rb +93 -4
  48. data/lib/bson/time.rb +63 -4
  49. data/lib/bson/time_with_zone.rb +1 -1
  50. data/lib/bson/timestamp.rb +16 -2
  51. data/lib/bson/true_class.rb +1 -1
  52. data/lib/bson/undefined.rb +12 -1
  53. data/lib/bson/version.rb +2 -2
  54. data/spec/bson/array_spec.rb +1 -1
  55. data/spec/bson/binary_spec.rb +34 -4
  56. data/spec/bson/binary_uuid_spec.rb +1 -1
  57. data/spec/bson/boolean_spec.rb +1 -1
  58. data/spec/bson/code_spec.rb +1 -1
  59. data/spec/bson/code_with_scope_spec.rb +1 -1
  60. data/spec/bson/date_spec.rb +1 -1
  61. data/spec/bson/date_time_spec.rb +1 -1
  62. data/spec/bson/decimal128_spec.rb +1 -1
  63. data/spec/bson/document_spec.rb +1 -1
  64. data/spec/bson/ext_json_parse_spec.rb +308 -0
  65. data/spec/bson/false_class_spec.rb +1 -1
  66. data/spec/bson/float_spec.rb +37 -1
  67. data/spec/bson/hash_spec.rb +71 -1
  68. data/spec/bson/int32_spec.rb +21 -1
  69. data/spec/bson/int64_spec.rb +39 -1
  70. data/spec/bson/integer_spec.rb +27 -1
  71. data/spec/bson/json_spec.rb +1 -1
  72. data/spec/bson/max_key_spec.rb +1 -1
  73. data/spec/bson/min_key_spec.rb +1 -1
  74. data/spec/bson/nil_class_spec.rb +1 -1
  75. data/spec/bson/object_id_spec.rb +1 -1
  76. data/spec/bson/object_spec.rb +1 -1
  77. data/spec/bson/open_struct_spec.rb +1 -1
  78. data/spec/bson/raw_spec.rb +22 -1
  79. data/spec/bson/regexp_spec.rb +1 -1
  80. data/spec/bson/registry_spec.rb +1 -1
  81. data/spec/bson/string_spec.rb +1 -1
  82. data/spec/bson/symbol_raw_spec.rb +45 -0
  83. data/spec/bson/symbol_spec.rb +61 -1
  84. data/spec/bson/time_spec.rb +205 -2
  85. data/spec/bson/time_with_zone_spec.rb +1 -1
  86. data/spec/bson/timestamp_spec.rb +1 -1
  87. data/spec/bson/true_class_spec.rb +1 -1
  88. data/spec/bson/undefined_spec.rb +1 -1
  89. data/spec/bson_spec.rb +1 -1
  90. data/spec/{support → runners}/common_driver.rb +1 -1
  91. data/spec/runners/corpus.rb +185 -0
  92. data/spec/{support/corpus.rb → runners/corpus_legacy.rb} +41 -59
  93. data/spec/spec_helper.rb +10 -3
  94. data/spec/{bson/driver_bson_spec.rb → spec_tests/common_driver_spec.rb} +1 -0
  95. data/spec/{bson/corpus_spec.rb → spec_tests/corpus_legacy_spec.rb} +4 -4
  96. data/spec/spec_tests/corpus_spec.rb +124 -0
  97. data/spec/spec_tests/data/corpus/README.md +15 -0
  98. data/spec/spec_tests/data/corpus/array.json +49 -0
  99. data/spec/spec_tests/data/corpus/binary.json +85 -0
  100. data/spec/spec_tests/data/corpus/boolean.json +27 -0
  101. data/spec/spec_tests/data/corpus/code.json +67 -0
  102. data/spec/spec_tests/data/corpus/code_w_scope.json +78 -0
  103. data/spec/spec_tests/data/corpus/datetime.json +42 -0
  104. data/spec/spec_tests/data/corpus/dbpointer.json +56 -0
  105. data/spec/spec_tests/data/corpus/dbref.json +31 -0
  106. data/spec/spec_tests/data/corpus/decimal128-1.json +317 -0
  107. data/spec/spec_tests/data/corpus/decimal128-2.json +793 -0
  108. data/spec/spec_tests/data/corpus/decimal128-3.json +1771 -0
  109. data/spec/spec_tests/data/corpus/decimal128-4.json +117 -0
  110. data/spec/spec_tests/data/corpus/decimal128-5.json +402 -0
  111. data/spec/spec_tests/data/corpus/decimal128-6.json +119 -0
  112. data/spec/spec_tests/data/corpus/decimal128-7.json +323 -0
  113. data/spec/spec_tests/data/corpus/document.json +36 -0
  114. data/spec/spec_tests/data/corpus/double.json +87 -0
  115. data/spec/spec_tests/data/corpus/int32.json +43 -0
  116. data/spec/spec_tests/data/corpus/int64.json +43 -0
  117. data/spec/spec_tests/data/corpus/maxkey.json +12 -0
  118. data/spec/spec_tests/data/corpus/minkey.json +12 -0
  119. data/spec/spec_tests/data/corpus/multi-type-deprecated.json +15 -0
  120. data/spec/spec_tests/data/corpus/multi-type.json +11 -0
  121. data/spec/spec_tests/data/corpus/null.json +12 -0
  122. data/spec/spec_tests/data/corpus/oid.json +28 -0
  123. data/spec/spec_tests/data/corpus/regex.json +65 -0
  124. data/spec/spec_tests/data/corpus/string.json +72 -0
  125. data/spec/spec_tests/data/corpus/symbol.json +80 -0
  126. data/spec/spec_tests/data/corpus/timestamp.json +24 -0
  127. data/spec/spec_tests/data/corpus/top.json +236 -0
  128. data/spec/spec_tests/data/corpus/undefined.json +15 -0
  129. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/array.json +0 -0
  130. data/spec/{support/corpus-tests/failures → spec_tests/data/corpus_legacy}/binary.json +0 -0
  131. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/boolean.json +0 -0
  132. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/code.json +1 -1
  133. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/code_w_scope.json +1 -1
  134. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/document.json +1 -1
  135. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/double.json +1 -1
  136. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/datetime.json +0 -0
  137. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/dbpointer.json +0 -0
  138. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/int64.json +0 -0
  139. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/symbol.json +0 -0
  140. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/int32.json +1 -1
  141. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/maxkey.json +1 -1
  142. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/minkey.json +1 -1
  143. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/null.json +1 -1
  144. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/oid.json +0 -0
  145. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/regex.json +1 -1
  146. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/string.json +0 -0
  147. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/timestamp.json +1 -1
  148. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/top.json +0 -0
  149. data/spec/{support/corpus-tests/failures → spec_tests/data/corpus_legacy}/undefined.json +0 -0
  150. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-1.json +0 -0
  151. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-2.json +0 -0
  152. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-3.json +0 -0
  153. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-4.json +0 -0
  154. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-5.json +0 -0
  155. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-6.json +0 -0
  156. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-7.json +0 -0
  157. data/spec/support/shared_examples.rb +1 -1
  158. metadata +176 -102
  159. metadata.gz.sig +0 -0
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2016-2019 MongoDB Inc.
1
+ # Copyright (C) 2016-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2019 MongoDB Inc.
1
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -205,7 +205,22 @@ module BSON
205
205
  #
206
206
  # @since 4.2.0
207
207
  def as_json(*args)
208
- { "$regex" => source, "$options" => options }
208
+ as_extended_json(mode: :legacy)
209
+ end
210
+
211
+ # Converts this object to a representation directly serializable to
212
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
213
+ #
214
+ # @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
215
+ # (default is canonical extended JSON)
216
+ #
217
+ # @return [ Hash ] The extended json representation.
218
+ def as_extended_json(**opts)
219
+ if opts[:mode] == :legacy
220
+ { "$regex" => source, "$options" => options }
221
+ else
222
+ {"$regularExpression" => {'pattern' => source, "options" => options}}
223
+ end
209
224
  end
210
225
 
211
226
  # Check equality of the raw bson regexp against another.
@@ -248,12 +263,14 @@ module BSON
248
263
  #
249
264
  # @param [ ByteBuffer ] buffer The byte buffer.
250
265
  #
266
+ # @option opts [ nil | :bson ] :mode Decoding mode to use.
267
+ #
251
268
  # @return [ Regexp ] The decoded regular expression.
252
269
  #
253
270
  # @see http://bsonspec.org/#/specification
254
271
  #
255
272
  # @since 2.0.0
256
- def from_bson(buffer)
273
+ def from_bson(buffer, **opts)
257
274
  pattern = buffer.get_cstring
258
275
  options = buffer.get_cstring
259
276
  Raw.new(pattern, options)
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2019 MongoDB Inc.
1
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2019 MongoDB Inc.
1
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -61,12 +61,14 @@ module BSON
61
61
  #
62
62
  # @param [ ByteBuffer ] buffer The byte buffer.
63
63
  #
64
+ # @option options [ nil | :bson ] :mode Decoding mode to use.
65
+ #
64
66
  # @return [ Specialized ] The decoded specialized class.
65
67
  #
66
68
  # @see http://bsonspec.org/#/specification
67
69
  #
68
70
  # @since 2.0.0
69
- def from_bson(buffer)
71
+ def from_bson(buffer, **options)
70
72
  new
71
73
  end
72
74
  end
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
- # Copyright (C) 2009-2019 MongoDB Inc.
2
+ # Copyright (C) 2009-2020 MongoDB Inc.
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -124,12 +124,14 @@ module BSON
124
124
  #
125
125
  # @param [ ByteBuffer ] buffer The byte buffer.
126
126
  #
127
+ # @option options [ nil | :bson ] :mode Decoding mode to use.
128
+ #
127
129
  # @return [ Regexp ] The decoded string.
128
130
  #
129
131
  # @see http://bsonspec.org/#/specification
130
132
  #
131
133
  # @since 2.0.0
132
- def from_bson(buffer)
134
+ def from_bson(buffer, **options)
133
135
  buffer.get_string
134
136
  end
135
137
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2019 MongoDB Inc.
1
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -89,19 +89,108 @@ module BSON
89
89
  to_s
90
90
  end
91
91
 
92
+ # Converts this object to a representation directly serializable to
93
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
94
+ #
95
+ # @option options [ true | false ] :relaxed Whether to produce relaxed
96
+ # extended JSON representation.
97
+ #
98
+ # @return [ Hash ] The extended json representation.
99
+ def as_extended_json(**options)
100
+ { "$symbol" => to_s }
101
+ end
102
+
103
+ class Raw
104
+ # Create a BSON Symbol
105
+ #
106
+ # @param [ String | Symbol ] str_or_sym The symbol represented by this
107
+ # object. Can be specified as a Symbol or a String.
108
+ #
109
+ # @see http://bsonspec.org/#/specification
110
+ def initialize(str_or_sym)
111
+ unless str_or_sym.is_a?(String) || str_or_sym.is_a?(Symbol)
112
+ raise ArgumentError, "BSON::Symbol::Raw must be given a symbol or a string, not #{str_or_sym}"
113
+ end
114
+
115
+ @symbol = str_or_sym.to_sym
116
+ end
117
+
118
+ # Get the underlying symbol as a Ruby symbol.
119
+ #
120
+ # @return [ Symbol ] The symbol represented by this BSON object.
121
+ def to_sym
122
+ @symbol
123
+ end
124
+
125
+ # Get the underlying symbol as a Ruby string.
126
+ #
127
+ # @return [ String ] The symbol as a string.
128
+ def to_s
129
+ @symbol.to_s
130
+ end
131
+
132
+ # Check equality of the raw bson symbol against another.
133
+ #
134
+ # @param [ Object ] other The object to check against.
135
+ #
136
+ # @return [ true, false ] If the objects are equal.
137
+ def ==(other)
138
+ return false unless other.is_a?(Raw)
139
+ to_sym == other.to_sym
140
+ end
141
+ alias :eql? :==
142
+
143
+ # Get the symbol as encoded BSON.
144
+ #
145
+ # @raise [ EncodingError ] If the symbol is not UTF-8.
146
+ #
147
+ # @return [ BSON::ByteBuffer ] The buffer with the encoded object.
148
+ #
149
+ # @see http://bsonspec.org/#/specification
150
+ def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
151
+ buffer.put_string(to_s)
152
+ end
153
+
154
+ def bson_type
155
+ Symbol::BSON_TYPE
156
+ end
157
+
158
+ # Converts this object to a representation directly serializable to
159
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
160
+ #
161
+ # This method returns the integer value if relaxed representation is
162
+ # requested, otherwise a $numberLong hash.
163
+ #
164
+ # @option options [ true | false ] :relaxed Whether to produce relaxed
165
+ # extended JSON representation.
166
+ #
167
+ # @return [ Hash | Integer ] The extended json representation.
168
+ def as_extended_json(**options)
169
+ {'$symbol' => to_s}
170
+ end
171
+ end
172
+
92
173
  module ClassMethods
93
174
 
94
175
  # Deserialize a symbol from BSON.
95
176
  #
96
177
  # @param [ ByteBuffer ] buffer The byte buffer.
97
178
  #
98
- # @return [ Regexp ] The decoded symbol.
179
+ # @option options [ nil | :bson ] :mode Decoding mode to use.
180
+ #
181
+ # @return [ Symbol | BSON::Symbol::Raw ] The decoded symbol.
99
182
  #
100
183
  # @see http://bsonspec.org/#/specification
101
184
  #
102
185
  # @since 2.0.0
103
- def from_bson(buffer)
104
- buffer.get_string.intern
186
+ def from_bson(buffer, **options)
187
+ sym = buffer.get_string.intern
188
+
189
+ if options[:mode] == :bson
190
+ Raw.new(sym)
191
+ else
192
+ sym
193
+ end
105
194
  end
106
195
  end
107
196
 
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2019 MongoDB Inc.
1
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -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,7 +54,48 @@ module BSON
38
54
  #
39
55
  # @since 2.0.0
40
56
  def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
41
- buffer.put_int64((to_i * 1000) + (usec / 1000))
57
+ value = _bson_to_i * 1000 + usec.divmod(1000).first
58
+ buffer.put_int64(value)
59
+ end
60
+
61
+ # Converts this object to a representation directly serializable to
62
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
63
+ #
64
+ # @note The time is floored to the nearest millisecond.
65
+ #
66
+ # @option options [ true | false ] :relaxed Whether to produce relaxed
67
+ # extended JSON representation.
68
+ #
69
+ # @return [ Hash ] The extended json representation.
70
+ def as_extended_json(**options)
71
+ utc_time = utc
72
+ if options[:mode] == :relaxed && (1970..9999).include?(utc_time.year)
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
80
+ {'$date' => utc_time.strftime('%Y-%m-%dT%H:%M:%S.%LZ')}
81
+ else
82
+ {'$date' => utc_time.strftime('%Y-%m-%dT%H:%M:%SZ')}
83
+ end
84
+ else
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
98
+ end
42
99
  end
43
100
 
44
101
  module ClassMethods
@@ -47,13 +104,15 @@ module BSON
47
104
  #
48
105
  # @param [ ByteBuffer ] buffer The byte buffer.
49
106
  #
107
+ # @option options [ nil | :bson ] :mode Decoding mode to use.
108
+ #
50
109
  # @return [ Time ] The decoded UTC datetime.
51
110
  #
52
111
  # @see http://bsonspec.org/#/specification
53
112
  #
54
113
  # @since 2.0.0
55
- def from_bson(buffer)
56
- seconds, fragment = Int64.from_bson(buffer).divmod(1000)
114
+ def from_bson(buffer, **options)
115
+ seconds, fragment = Int64.from_bson(buffer, mode: nil).divmod(1000)
57
116
  at(seconds, fragment * 1000).utc
58
117
  end
59
118
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2018-2019 MongoDB Inc.
1
+ # Copyright (C) 2018-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2019 MongoDB Inc.
1
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -84,7 +84,19 @@ module BSON
84
84
  # @return [ Hash ] The timestamp as a JSON hash.
85
85
  #
86
86
  # @since 2.0.0
87
+ # @deprecated Use as_extended_json instead.
87
88
  def as_json(*args)
89
+ as_extended_json
90
+ end
91
+
92
+ # Converts this object to a representation directly serializable to
93
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
94
+ #
95
+ # @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
96
+ # (default is canonical extended JSON)
97
+ #
98
+ # @return [ Hash ] The extended json representation.
99
+ def as_extended_json(**options)
88
100
  { "$timestamp" => { "t" => seconds, "i" => increment } }
89
101
  end
90
102
 
@@ -120,12 +132,14 @@ module BSON
120
132
  #
121
133
  # @param [ ByteBuffer ] buffer The byte buffer.
122
134
  #
135
+ # @option options [ nil | :bson ] :mode Decoding mode to use.
136
+ #
123
137
  # @return [ Timestamp ] The decoded timestamp.
124
138
  #
125
139
  # @see http://bsonspec.org/#/specification
126
140
  #
127
141
  # @since 2.0.0
128
- def self.from_bson(buffer)
142
+ def self.from_bson(buffer, **options)
129
143
  increment = buffer.get_int32
130
144
  seconds = buffer.get_int32
131
145
  new(seconds, increment)
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2019 MongoDB Inc.
1
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2019 MongoDB Inc.
1
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -41,6 +41,17 @@ module BSON
41
41
  self.class == other.class
42
42
  end
43
43
 
44
+ # Converts this object to a representation directly serializable to
45
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
46
+ #
47
+ # @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
48
+ # (default is canonical extended JSON)
49
+ #
50
+ # @return [ Hash ] The extended json representation.
51
+ def as_extended_json(**options)
52
+ { "$undefined" => true }
53
+ end
54
+
44
55
  # Register this type when the module is loaded.
45
56
  #
46
57
  # @since 2.0.0
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2019 MongoDB Inc.
1
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -13,5 +13,5 @@
13
13
  # limitations under the License.
14
14
 
15
15
  module BSON
16
- VERSION = "4.7.1".freeze
16
+ VERSION = "4.9.1".freeze
17
17
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2019 MongoDB Inc.
1
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2019 MongoDB Inc.
1
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -63,7 +63,7 @@ describe BSON::Binary do
63
63
 
64
64
  it "returns the binary data plus type" do
65
65
  expect(object.as_json).to eq(
66
- { "$binary" => Base64.encode64("testing"), "$type" => :user }
66
+ { "$binary" => {'base64' => Base64.encode64("testing").strip, "subType" => '80' }}
67
67
  )
68
68
  end
69
69
 
@@ -126,12 +126,34 @@ describe BSON::Binary do
126
126
  end
127
127
 
128
128
  describe '#from_bson' do
129
- let(:bson) { BSON::ByteBuffer.new("#{5.to_bson}#{0.chr}hello".force_encoding('BINARY')) }
130
- let(:obj) { described_class.from_bson(bson) }
129
+ let(:buffer) { BSON::ByteBuffer.new(bson) }
130
+ let(:obj) { described_class.from_bson(buffer) }
131
+
132
+ let(:bson) { "#{5.to_bson}#{0.chr}hello".force_encoding('BINARY') }
131
133
 
132
134
  it 'sets data encoding to binary' do
133
135
  expect(obj.data.encoding).to eq(Encoding.find('BINARY'))
134
136
  end
137
+
138
+ context 'when binary subtype is supported' do
139
+ let(:bson) { [3, 0, 0, 0, 1].map(&:chr).join.force_encoding('BINARY') + 'foo' }
140
+
141
+ it 'works' do
142
+ obj.should be_a(described_class)
143
+ obj.type.should be :function
144
+ end
145
+ end
146
+
147
+ context 'when binary subtype is not supported' do
148
+ let(:bson) { [3, 0, 0, 0, 16].map(&:chr).join.force_encoding('BINARY') + 'foo' }
149
+
150
+ it 'raises an exception' do
151
+ lambda do
152
+ obj
153
+ end.should raise_error(BSON::Error::UnsupportedBinarySubtype,
154
+ /BSON data contains unsupported binary subtype 0x10/)
155
+ end
156
+ end
135
157
  end
136
158
 
137
159
  describe "#to_bson/#from_bson" do
@@ -203,6 +225,14 @@ describe BSON::Binary do
203
225
  it_behaves_like "a deserializable bson element"
204
226
  end
205
227
 
228
+ context "when the type is :cyphertext" do
229
+ let(:obj) { described_class.new("testing", :ciphertext) }
230
+ let(:bson) { "#{7.to_bson}#{6.chr}testing" }
231
+
232
+ it_behaves_like "a serializable bson element"
233
+ it_behaves_like "a deserializable bson element"
234
+ end
235
+
206
236
  context 'when given binary string' do
207
237
  let(:obj) { described_class.new("\x00\xfe\xff".force_encoding('BINARY')) }
208
238
  let(:bson) { "#{3.to_bson}#{0.chr}\x00\xfe\xff".force_encoding('BINARY') }