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.
- checksums.yaml +4 -4
- data/README.md +94 -10
- data/Rakefile +68 -39
- data/ext/bson/bson-native.h +12 -4
- data/ext/bson/extconf.rb +8 -3
- data/ext/bson/init.c +11 -11
- data/ext/bson/read.c +39 -9
- data/ext/bson/util.c +171 -16
- data/ext/bson/write.c +34 -39
- data/lib/bson/active_support.rb +1 -0
- data/lib/bson/array.rb +58 -32
- data/lib/bson/big_decimal.rb +16 -6
- data/lib/bson/binary.rb +271 -129
- data/lib/bson/boolean.rb +1 -0
- data/lib/bson/code.rb +10 -12
- data/lib/bson/code_with_scope.rb +9 -11
- data/lib/bson/config.rb +1 -27
- data/lib/bson/date.rb +2 -1
- data/lib/bson/date_time.rb +2 -1
- data/lib/bson/db_pointer.rb +12 -13
- data/lib/bson/dbref.rb +11 -9
- data/lib/bson/decimal128/builder.rb +10 -9
- data/lib/bson/decimal128.rb +25 -111
- data/lib/bson/document.rb +1 -0
- data/lib/bson/environment.rb +1 -0
- data/lib/bson/error/bson_decode_error.rb +11 -0
- data/lib/bson/error/ext_json_parse_error.rb +11 -0
- data/lib/bson/error/illegal_key.rb +23 -0
- data/lib/bson/error/invalid_binary_type.rb +37 -0
- data/lib/bson/error/invalid_dbref_argument.rb +12 -0
- data/lib/bson/error/invalid_decimal128_argument.rb +25 -0
- data/lib/bson/error/invalid_decimal128_range.rb +27 -0
- data/lib/bson/error/invalid_decimal128_string.rb +26 -0
- data/lib/bson/error/invalid_key.rb +24 -0
- data/lib/bson/error/invalid_object_id.rb +11 -0
- data/lib/bson/error/invalid_regexp_pattern.rb +13 -0
- data/lib/bson/error/unrepresentable_precision.rb +19 -0
- data/lib/bson/error/unserializable_class.rb +13 -0
- data/lib/bson/error/unsupported_binary_subtype.rb +12 -0
- data/lib/bson/error/unsupported_type.rb +11 -0
- data/lib/bson/error.rb +16 -28
- data/lib/bson/ext_json.rb +2 -1
- data/lib/bson/false_class.rb +2 -1
- data/lib/bson/float.rb +3 -2
- data/lib/bson/hash.rb +128 -73
- data/lib/bson/int32.rb +17 -5
- data/lib/bson/int64.rb +17 -5
- data/lib/bson/integer.rb +4 -5
- data/lib/bson/json.rb +1 -0
- data/lib/bson/max_key.rb +8 -10
- data/lib/bson/min_key.rb +8 -10
- data/lib/bson/nil_class.rb +1 -0
- data/lib/bson/object.rb +7 -27
- data/lib/bson/object_id.rb +84 -120
- data/lib/bson/open_struct.rb +3 -2
- data/lib/bson/regexp.rb +36 -65
- data/lib/bson/registry.rb +2 -6
- data/lib/bson/specialized.rb +2 -1
- data/lib/bson/string.rb +4 -27
- data/lib/bson/symbol.rb +23 -20
- data/lib/bson/time.rb +3 -2
- data/lib/bson/time_with_zone.rb +13 -1
- data/lib/bson/timestamp.rb +3 -2
- data/lib/bson/true_class.rb +2 -1
- data/lib/bson/undefined.rb +15 -1
- data/lib/bson/version.rb +3 -1
- data/lib/bson.rb +3 -2
- data/spec/bson/array_spec.rb +19 -60
- data/spec/bson/big_decimal_spec.rb +16 -4
- data/spec/bson/binary_spec.rb +129 -81
- data/spec/bson/binary_uuid_spec.rb +1 -0
- data/spec/bson/boolean_spec.rb +1 -0
- data/spec/bson/byte_buffer_read_spec.rb +1 -0
- data/spec/bson/byte_buffer_spec.rb +1 -0
- data/spec/bson/byte_buffer_write_spec.rb +1 -0
- data/spec/bson/code_spec.rb +5 -3
- data/spec/bson/code_with_scope_spec.rb +5 -3
- data/spec/bson/config_spec.rb +1 -35
- data/spec/bson/date_spec.rb +1 -0
- data/spec/bson/date_time_spec.rb +1 -0
- data/spec/bson/dbref_legacy_spec.rb +20 -3
- data/spec/bson/dbref_spec.rb +9 -9
- data/spec/bson/decimal128_spec.rb +40 -20
- data/spec/bson/document_as_spec.rb +1 -0
- data/spec/bson/document_spec.rb +1 -1
- data/spec/bson/ext_json_parse_spec.rb +1 -0
- data/spec/bson/false_class_spec.rb +8 -0
- data/spec/bson/float_spec.rb +8 -3
- data/spec/bson/hash_as_spec.rb +1 -0
- data/spec/bson/hash_spec.rb +87 -75
- data/spec/bson/int32_spec.rb +21 -6
- data/spec/bson/int64_spec.rb +21 -6
- data/spec/bson/integer_spec.rb +45 -13
- data/spec/bson/json_spec.rb +1 -0
- data/spec/bson/max_key_spec.rb +5 -3
- data/spec/bson/min_key_spec.rb +5 -3
- data/spec/bson/nil_class_spec.rb +1 -0
- data/spec/bson/object_id_spec.rb +57 -4
- data/spec/bson/object_spec.rb +2 -1
- data/spec/bson/open_struct_spec.rb +14 -71
- data/spec/bson/raw_spec.rb +9 -15
- data/spec/bson/regexp_spec.rb +4 -3
- data/spec/bson/registry_spec.rb +2 -1
- data/spec/bson/string_spec.rb +13 -38
- data/spec/bson/symbol_raw_spec.rb +25 -0
- data/spec/bson/symbol_spec.rb +15 -18
- data/spec/bson/time_spec.rb +1 -0
- data/spec/bson/time_with_zone_spec.rb +1 -0
- data/spec/bson/timestamp_spec.rb +1 -0
- data/spec/bson/true_class_spec.rb +8 -0
- data/spec/bson/undefined_spec.rb +27 -0
- data/spec/bson_spec.rb +1 -0
- data/spec/runners/common_driver.rb +6 -5
- data/spec/runners/corpus.rb +6 -0
- data/spec/runners/corpus_legacy.rb +1 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/spec_tests/common_driver_spec.rb +9 -4
- data/spec/spec_tests/corpus_legacy_spec.rb +1 -0
- data/spec/spec_tests/corpus_spec.rb +13 -3
- data/spec/spec_tests/data/corpus/binary.json +5 -0
- data/spec/spec_tests/data/corpus/code.json +13 -13
- data/spec/spec_tests/data/corpus/decimal128-4.json +48 -0
- data/spec/spec_tests/data/corpus/decimal128-6.json +12 -0
- data/spec/spec_tests/data/corpus/decimal128-7.json +4 -0
- data/spec/spec_tests/data/corpus/document.json +20 -0
- data/spec/spec_tests/data/corpus/symbol.json +7 -7
- data/spec/spec_tests/data/corpus/top.json +18 -3
- data/spec/support/shared_examples.rb +28 -5
- data/spec/support/spec_config.rb +1 -0
- data/spec/support/utils.rb +49 -1
- metadata +114 -164
- checksums.yaml.gz.sig +0 -0
- data/spec/shared/LICENSE +0 -20
- data/spec/shared/bin/get-mongodb-download-url +0 -17
- data/spec/shared/bin/s3-copy +0 -45
- data/spec/shared/bin/s3-upload +0 -69
- data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
- data/spec/shared/lib/mrss/cluster_config.rb +0 -231
- data/spec/shared/lib/mrss/constraints.rb +0 -386
- data/spec/shared/lib/mrss/docker_runner.rb +0 -271
- data/spec/shared/lib/mrss/event_subscriber.rb +0 -200
- data/spec/shared/lib/mrss/lite_constraints.rb +0 -191
- data/spec/shared/lib/mrss/server_version_registry.rb +0 -120
- data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
- data/spec/shared/lib/mrss/utils.rb +0 -15
- data/spec/shared/share/Dockerfile.erb +0 -338
- data/spec/shared/share/haproxy-1.conf +0 -16
- data/spec/shared/share/haproxy-2.conf +0 -17
- data/spec/shared/shlib/distro.sh +0 -74
- data/spec/shared/shlib/server.sh +0 -367
- data/spec/shared/shlib/set_env.sh +0 -131
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -1
data/lib/bson/big_decimal.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
# rubocop:todo all
|
2
3
|
# Copyright (C) 2009-2021 MongoDB Inc.
|
3
4
|
#
|
4
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -21,7 +22,7 @@ module BSON
|
|
21
22
|
# @see http://bsonspec.org/#/specification
|
22
23
|
module BigDecimal
|
23
24
|
|
24
|
-
# BigDecimals are serialized as Decimal128s under the hood. A Decimal128
|
25
|
+
# BigDecimals are serialized as Decimal128s under the hood. A Decimal128
|
25
26
|
# is type 0x13 in the BSON spec.
|
26
27
|
BSON_TYPE = ::String.new(19.chr, encoding: BINARY).freeze
|
27
28
|
|
@@ -33,8 +34,8 @@ module BSON
|
|
33
34
|
# @return [ BSON::ByteBuffer ] The buffer with the encoded object.
|
34
35
|
#
|
35
36
|
# @see http://bsonspec.org/#/specification
|
36
|
-
def to_bson(buffer = ByteBuffer.new
|
37
|
-
BSON::Decimal128.new(to_s).to_bson(buffer
|
37
|
+
def to_bson(buffer = ByteBuffer.new)
|
38
|
+
BSON::Decimal128.new(to_s).to_bson(buffer)
|
38
39
|
end
|
39
40
|
|
40
41
|
# Get the BSON type for BigDecimal. This is the same BSON type as
|
@@ -45,7 +46,8 @@ module BSON
|
|
45
46
|
|
46
47
|
module ClassMethods
|
47
48
|
|
48
|
-
# Deserialize the BigDecimal from raw BSON bytes.
|
49
|
+
# Deserialize the BigDecimal from raw BSON bytes. If the :mode option
|
50
|
+
# is set to BSON, this will return a BSON::Decimal128
|
49
51
|
#
|
50
52
|
# @example Get the BigDecimal from BSON.
|
51
53
|
# BigDecimal.from_bson(bson)
|
@@ -54,11 +56,19 @@ module BSON
|
|
54
56
|
#
|
55
57
|
# @option options [ nil | :bson ] :mode Decoding mode to use.
|
56
58
|
#
|
57
|
-
# @return [ BigDecimal ] The decimal object.
|
59
|
+
# @return [ BigDecimal | BSON::Decimal128 ] The decimal object.
|
58
60
|
def from_bson(buffer, **options)
|
59
|
-
Decimal128.from_bson(buffer, **options)
|
61
|
+
dec128 = Decimal128.from_bson(buffer, **options)
|
62
|
+
if options[:mode] == :bson
|
63
|
+
dec128
|
64
|
+
else
|
65
|
+
dec128.to_d
|
66
|
+
end
|
60
67
|
end
|
61
68
|
end
|
69
|
+
|
70
|
+
# Register this type when the module is loaded.
|
71
|
+
Registry.register(BSON_TYPE, ::BigDecimal)
|
62
72
|
end
|
63
73
|
|
64
74
|
# Enrich the core BigDecimal class with this module.
|
data/lib/bson/binary.rb
CHANGED
@@ -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");
|
@@ -16,7 +17,6 @@
|
|
16
17
|
require 'base64'
|
17
18
|
|
18
19
|
module BSON
|
19
|
-
|
20
20
|
# Represents binary data.
|
21
21
|
#
|
22
22
|
# @see http://bsonspec.org/#/specification
|
@@ -24,6 +24,7 @@ module BSON
|
|
24
24
|
# @since 2.0.0
|
25
25
|
class Binary
|
26
26
|
include JSON
|
27
|
+
include Comparable
|
27
28
|
|
28
29
|
# A binary is type 0x05 in the BSON spec.
|
29
30
|
#
|
@@ -40,17 +41,21 @@ module BSON
|
|
40
41
|
#
|
41
42
|
# @since 2.0.0
|
42
43
|
SUBTYPES = {
|
43
|
-
:
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
47
|
-
:
|
48
|
-
:
|
49
|
-
:
|
50
|
-
:
|
51
|
-
:
|
44
|
+
generic: 0.chr,
|
45
|
+
function: 1.chr,
|
46
|
+
old: 2.chr,
|
47
|
+
uuid_old: 3.chr,
|
48
|
+
uuid: 4.chr,
|
49
|
+
md5: 5.chr,
|
50
|
+
ciphertext: 6.chr,
|
51
|
+
column: 7.chr,
|
52
|
+
sensitive: 8.chr,
|
53
|
+
user: 128.chr,
|
52
54
|
}.freeze
|
53
55
|
|
56
|
+
# The starting point of the user-defined subtype range.
|
57
|
+
USER_SUBTYPE = 0x80
|
58
|
+
|
54
59
|
# The mappings of single byte subtypes to their symbol counterparts.
|
55
60
|
#
|
56
61
|
# @since 2.0.0
|
@@ -64,10 +69,11 @@ module BSON
|
|
64
69
|
attr_reader :data
|
65
70
|
|
66
71
|
# @return [ Symbol ] The binary type.
|
67
|
-
#
|
68
|
-
# @since 2.0.0
|
69
72
|
attr_reader :type
|
70
73
|
|
74
|
+
# @return [ String ] The raw type value, as an encoded integer.
|
75
|
+
attr_reader :raw_type
|
76
|
+
|
71
77
|
# Determine if this binary object is equal to another object.
|
72
78
|
#
|
73
79
|
# @example Check the binary equality.
|
@@ -80,10 +86,25 @@ module BSON
|
|
80
86
|
# @since 2.0.0
|
81
87
|
def ==(other)
|
82
88
|
return false unless other.is_a?(Binary)
|
89
|
+
|
83
90
|
type == other.type && data == other.data
|
84
91
|
end
|
85
92
|
alias eql? ==
|
86
93
|
|
94
|
+
# Compare this binary object to another object. The two objects must have
|
95
|
+
# the same type for any meaningful comparison.
|
96
|
+
#
|
97
|
+
# @param [ Object ] other The object to compare against.
|
98
|
+
#
|
99
|
+
# @return [ Integer | nil ] If the objects have the same type, the result
|
100
|
+
# is -1 if self < other, 0 if self == other, and 1 if self > other. If
|
101
|
+
# other is not a Binary, or is a Binary of a different type, returns nil.
|
102
|
+
def <=>(other)
|
103
|
+
return nil unless other.is_a?(Binary) && type == other.type
|
104
|
+
|
105
|
+
data <=> other.data
|
106
|
+
end
|
107
|
+
|
87
108
|
# Generates a Fixnum hash value for this object.
|
88
109
|
#
|
89
110
|
# Allows using Binary as hash keys.
|
@@ -92,41 +113,36 @@ module BSON
|
|
92
113
|
#
|
93
114
|
# @since 2.3.1
|
94
115
|
def hash
|
95
|
-
data
|
116
|
+
[ data, type ].hash
|
96
117
|
end
|
97
118
|
|
98
|
-
#
|
99
|
-
#
|
100
|
-
#
|
101
|
-
#
|
119
|
+
# Return a representation of the object for use in
|
120
|
+
# application-level JSON serialization. Since BSON::Binary
|
121
|
+
# is used exclusively in BSON-related contexts, this
|
122
|
+
# method returns the canonical Extended JSON representation.
|
102
123
|
#
|
103
|
-
# @return [ Hash ] The
|
104
|
-
|
105
|
-
# @since 2.0.0
|
106
|
-
# @deprecated Use as_extended_json instead.
|
107
|
-
def as_json(*args)
|
124
|
+
# @return [ Hash ] The extended json representation.
|
125
|
+
def as_json(*_args)
|
108
126
|
as_extended_json
|
109
127
|
end
|
110
128
|
|
111
129
|
# Converts this object to a representation directly serializable to
|
112
|
-
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.
|
130
|
+
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
|
113
131
|
#
|
114
132
|
# @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
|
115
133
|
# (default is canonical extended JSON)
|
116
134
|
#
|
117
135
|
# @return [ Hash ] The extended json representation.
|
118
136
|
def as_extended_json(**options)
|
119
|
-
subtype =
|
120
|
-
if subtype.length == 1
|
121
|
-
subtype = "0#{subtype}"
|
122
|
-
end
|
137
|
+
subtype = @raw_type.each_byte.map { |c| c.to_s(16) }.join
|
138
|
+
subtype = "0#{subtype}" if subtype.length == 1
|
123
139
|
|
124
140
|
value = Base64.encode64(data).strip
|
125
141
|
|
126
142
|
if options[:mode] == :legacy
|
127
|
-
{
|
143
|
+
{ '$binary' => value, '$type' => subtype }
|
128
144
|
else
|
129
|
-
{
|
145
|
+
{ '$binary' => { 'base64' => value, 'subType' => subtype } }
|
130
146
|
end
|
131
147
|
end
|
132
148
|
|
@@ -146,20 +162,17 @@ module BSON
|
|
146
162
|
# @param [ Symbol ] type The binary type.
|
147
163
|
#
|
148
164
|
# @since 2.0.0
|
149
|
-
def initialize(data =
|
150
|
-
|
151
|
-
|
152
|
-
# The Binary class used to force encoding to BINARY when serializing to
|
153
|
-
# BSON. Instead of doing that during serialization, perform this
|
154
|
-
# operation during Binary construction to make it clear that once
|
155
|
-
# the string is given to the Binary, the data is treated as a binary
|
156
|
-
# string and not a text string in any encoding.
|
157
|
-
unless data.encoding == Encoding.find('BINARY')
|
158
|
-
data = data.dup.force_encoding('BINARY')
|
159
|
-
end
|
165
|
+
def initialize(data = '', type = :generic)
|
166
|
+
initialize_instance(data, type)
|
167
|
+
end
|
160
168
|
|
161
|
-
|
162
|
-
|
169
|
+
# For legacy deserialization support where BSON::Binary objects are
|
170
|
+
# expected to have a specific internal representation (with only
|
171
|
+
# @type and @data instance variables).
|
172
|
+
#
|
173
|
+
# @api private
|
174
|
+
def init_with(coder)
|
175
|
+
initialize_instance(coder['data'], coder['type'])
|
163
176
|
end
|
164
177
|
|
165
178
|
# Get a nice string for use with object inspection.
|
@@ -202,37 +215,15 @@ module BSON
|
|
202
215
|
# @api experimental
|
203
216
|
def to_uuid(representation = nil)
|
204
217
|
if representation.is_a?(String)
|
205
|
-
raise ArgumentError,
|
218
|
+
raise ArgumentError,
|
219
|
+
"Representation must be given as a symbol: #{representation.inspect}"
|
206
220
|
end
|
221
|
+
|
207
222
|
case type
|
208
223
|
when :uuid
|
209
|
-
|
210
|
-
raise ArgumentError, "Binary of type :uuid can only be stringified to :standard representation, requested: #{representation.inspect}"
|
211
|
-
end
|
212
|
-
|
213
|
-
data.split('').map { |n| '%02x' % n.ord }.join.sub(/\A(.{8})(.{4})(.{4})(.{4})(.{12})\z/, '\1-\2-\3-\4-\5')
|
224
|
+
from_uuid_to_uuid(representation || :standard)
|
214
225
|
when :uuid_old
|
215
|
-
|
216
|
-
raise ArgumentError, 'Representation must be specified for BSON::Binary objects of type :uuid_old'
|
217
|
-
end
|
218
|
-
|
219
|
-
hex = data.split('').map { |n| '%02x' % n.ord }.join
|
220
|
-
|
221
|
-
case representation
|
222
|
-
when :standard
|
223
|
-
raise ArgumentError, 'BSON::Binary objects of type :uuid_old cannot be stringified to :standard representation'
|
224
|
-
when :csharp_legacy
|
225
|
-
hex.sub(/\A(..)(..)(..)(..)(..)(..)(..)(..)(.{16})\z/, '\4\3\2\1\6\5\8\7\9')
|
226
|
-
when :java_legacy
|
227
|
-
hex.sub(/\A(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)\z/) do |m|
|
228
|
-
"#{$8}#{$7}#{$6}#{$5}#{$4}#{$3}#{$2}#{$1}" +
|
229
|
-
"#{$16}#{$15}#{$14}#{$13}#{$12}#{$11}#{$10}#{$9}"
|
230
|
-
end
|
231
|
-
when :python_legacy
|
232
|
-
hex
|
233
|
-
else
|
234
|
-
raise ArgumentError, "Invalid representation: #{representation}"
|
235
|
-
end.sub(/\A(.{8})(.{4})(.{4})(.{4})(.{12})\z/, '\1-\2-\3-\4-\5')
|
226
|
+
from_uuid_old_to_uuid(representation)
|
236
227
|
else
|
237
228
|
raise TypeError, "The type of Binary must be :uuid or :uuid_old, this object is: #{type.inspect}"
|
238
229
|
end
|
@@ -248,10 +239,10 @@ module BSON
|
|
248
239
|
# @see http://bsonspec.org/#/specification
|
249
240
|
#
|
250
241
|
# @since 2.0.0
|
251
|
-
def to_bson(buffer = ByteBuffer.new
|
242
|
+
def to_bson(buffer = ByteBuffer.new)
|
252
243
|
position = buffer.length
|
253
244
|
buffer.put_int32(0)
|
254
|
-
buffer.put_byte(
|
245
|
+
buffer.put_byte(@raw_type)
|
255
246
|
buffer.put_int32(data.bytesize) if type == :old
|
256
247
|
buffer.put_bytes(data)
|
257
248
|
buffer.replace_int32(position, buffer.length - position - 5)
|
@@ -268,13 +259,19 @@ module BSON
|
|
268
259
|
# @see http://bsonspec.org/#/specification
|
269
260
|
#
|
270
261
|
# @since 2.0.0
|
271
|
-
def self.from_bson(buffer, **
|
262
|
+
def self.from_bson(buffer, **_options)
|
272
263
|
length = buffer.get_int32
|
273
264
|
type_byte = buffer.get_byte
|
274
|
-
|
275
|
-
if
|
276
|
-
|
277
|
-
|
265
|
+
|
266
|
+
if type_byte.bytes.first < USER_SUBTYPE
|
267
|
+
type = TYPES[type_byte]
|
268
|
+
|
269
|
+
if type.nil?
|
270
|
+
raise Error::UnsupportedBinarySubtype,
|
271
|
+
"BSON data contains unsupported binary subtype #{'0x%02x' % type_byte.ord}"
|
272
|
+
end
|
273
|
+
else
|
274
|
+
type = type_byte
|
278
275
|
end
|
279
276
|
|
280
277
|
length = buffer.get_int32 if type == :old
|
@@ -308,66 +305,166 @@ module BSON
|
|
308
305
|
#
|
309
306
|
# @api experimental
|
310
307
|
def self.from_uuid(uuid, representation = nil)
|
311
|
-
if representation.is_a?(String)
|
312
|
-
|
308
|
+
raise ArgumentError, "Representation must be given as a symbol: #{representation}" if representation.is_a?(String)
|
309
|
+
|
310
|
+
uuid_binary = uuid.delete('-').scan(/../).map(&:hex).map(&:chr).join
|
311
|
+
representation ||= :standard
|
312
|
+
|
313
|
+
handler = :"from_#{representation}_uuid"
|
314
|
+
raise ArgumentError, "Invalid representation: #{representation}" unless respond_to?(handler)
|
315
|
+
|
316
|
+
send(handler, uuid_binary)
|
317
|
+
end
|
318
|
+
|
319
|
+
# Constructs a new binary object from a standard-format binary UUID
|
320
|
+
# representation.
|
321
|
+
#
|
322
|
+
# @param [ String ] uuid_binary the UUID data
|
323
|
+
#
|
324
|
+
# @return [ BSON::Binary ] the Binary object
|
325
|
+
#
|
326
|
+
# @api private
|
327
|
+
def self.from_standard_uuid(uuid_binary)
|
328
|
+
new(uuid_binary, :uuid)
|
329
|
+
end
|
330
|
+
|
331
|
+
# Constructs a new binary object from a csharp legacy-format binary UUID
|
332
|
+
# representation.
|
333
|
+
#
|
334
|
+
# @param [ String ] uuid_binary the UUID data
|
335
|
+
#
|
336
|
+
# @return [ BSON::Binary ] the Binary object
|
337
|
+
#
|
338
|
+
# @api private
|
339
|
+
def self.from_csharp_legacy_uuid(uuid_binary)
|
340
|
+
uuid_binary.sub!(/\A(.)(.)(.)(.)(.)(.)(.)(.)(.{8})\z/, '\4\3\2\1\6\5\8\7\9')
|
341
|
+
new(uuid_binary, :uuid_old)
|
342
|
+
end
|
343
|
+
|
344
|
+
# Constructs a new binary object from a java legacy-format binary UUID
|
345
|
+
# representation.
|
346
|
+
#
|
347
|
+
# @param [ String ] uuid_binary the UUID data
|
348
|
+
#
|
349
|
+
# @return [ BSON::Binary ] the Binary object
|
350
|
+
#
|
351
|
+
# @api private
|
352
|
+
def self.from_java_legacy_uuid(uuid_binary)
|
353
|
+
uuid_binary.sub!(/\A(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)\z/) do
|
354
|
+
(::Regexp.last_match[1..8].reverse + ::Regexp.last_match[9..16].reverse).join
|
313
355
|
end
|
314
|
-
uuid_binary
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
356
|
+
new(uuid_binary, :uuid_old)
|
357
|
+
end
|
358
|
+
|
359
|
+
# Constructs a new binary object from a python legacy-format binary UUID
|
360
|
+
# representation.
|
361
|
+
#
|
362
|
+
# @param [ String ] uuid_binary the UUID data
|
363
|
+
#
|
364
|
+
# @return [ BSON::Binary ] the Binary object
|
365
|
+
#
|
366
|
+
# @api private
|
367
|
+
def self.from_python_legacy_uuid(uuid_binary)
|
368
|
+
new(uuid_binary, :uuid_old)
|
369
|
+
end
|
370
|
+
|
371
|
+
private
|
372
|
+
|
373
|
+
# initializes an instance of BSON::Binary.
|
374
|
+
#
|
375
|
+
# @param [ String ] data the data to initialize the object with
|
376
|
+
# @param [ Symbol ] type the type to assign the binary object
|
377
|
+
def initialize_instance(data, type)
|
378
|
+
@type = validate_type!(type)
|
379
|
+
|
380
|
+
# The Binary class used to force encoding to BINARY when serializing to
|
381
|
+
# BSON. Instead of doing that during serialization, perform this
|
382
|
+
# operation during Binary construction to make it clear that once
|
383
|
+
# the string is given to the Binary, the data is treated as a binary
|
384
|
+
# string and not a text string in any encoding.
|
385
|
+
data = data.dup.force_encoding('BINARY') unless data.encoding == Encoding.find('BINARY')
|
386
|
+
|
387
|
+
@data = data
|
388
|
+
end
|
389
|
+
|
390
|
+
# Converts the Binary UUID object to a UUID of the given representation.
|
391
|
+
# Currently, only :standard representation is supported.
|
392
|
+
#
|
393
|
+
# @param [ Symbol ] representation The representation to target (must be
|
394
|
+
# :standard)
|
395
|
+
#
|
396
|
+
# @return [ String ] the UUID as a string
|
397
|
+
def from_uuid_to_uuid(representation)
|
398
|
+
if representation != :standard
|
399
|
+
raise ArgumentError,
|
400
|
+
'Binary of type :uuid can only be stringified to :standard representation, ' \
|
401
|
+
"requested: #{representation.inspect}"
|
331
402
|
end
|
403
|
+
|
404
|
+
data
|
405
|
+
.chars
|
406
|
+
.map { |n| '%02x' % n.ord }
|
407
|
+
.join
|
408
|
+
.sub(/\A(.{8})(.{4})(.{4})(.{4})(.{12})\z/, '\1-\2-\3-\4-\5')
|
332
409
|
end
|
333
410
|
|
334
|
-
#
|
411
|
+
# Converts the UUID-old object to a UUID of the given representation.
|
335
412
|
#
|
336
|
-
# @
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
attr_reader :type
|
343
|
-
|
344
|
-
# Instantiate the new error.
|
345
|
-
#
|
346
|
-
# @example Instantiate the error.
|
347
|
-
# InvalidType.new(:error)
|
348
|
-
#
|
349
|
-
# @param [ Object ] type The invalid type.
|
350
|
-
#
|
351
|
-
# @since 2.0.0
|
352
|
-
def initialize(type)
|
353
|
-
@type = type
|
413
|
+
# @param [ Symbol ] representation The representation to target
|
414
|
+
#
|
415
|
+
# @return [ String ] the UUID as a string
|
416
|
+
def from_uuid_old_to_uuid(representation)
|
417
|
+
if representation.nil?
|
418
|
+
raise ArgumentError, 'Representation must be specified for BSON::Binary objects of type :uuid_old'
|
354
419
|
end
|
355
420
|
|
356
|
-
|
357
|
-
#
|
358
|
-
|
359
|
-
#
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
421
|
+
hex = data.chars.map { |n| '%02x' % n.ord }.join
|
422
|
+
handler = :"from_uuid_old_to_#{representation}_uuid"
|
423
|
+
|
424
|
+
raise ArgumentError, "Invalid representation: #{representation}" unless respond_to?(handler, true)
|
425
|
+
|
426
|
+
send(handler, hex)
|
427
|
+
.sub(/\A(.{8})(.{4})(.{4})(.{4})(.{12})\z/, '\1-\2-\3-\4-\5')
|
428
|
+
end
|
429
|
+
|
430
|
+
# Tries to convert a UUID-old object to a standard representation, which is
|
431
|
+
# not supported.
|
432
|
+
#
|
433
|
+
# @param [ String ] hex The hexadecimal string to convert
|
434
|
+
#
|
435
|
+
# @raise [ ArgumentError ] because standard representation is not supported
|
436
|
+
def from_uuid_old_to_standard_uuid(_hex)
|
437
|
+
raise ArgumentError, 'BSON::Binary objects of type :uuid_old cannot be stringified to :standard representation'
|
438
|
+
end
|
439
|
+
|
440
|
+
# Converts a UUID-old object to a csharp-legacy representation.
|
441
|
+
#
|
442
|
+
# @param [ String ] hex The hexadecimal string to convert
|
443
|
+
#
|
444
|
+
# @return [ String ] the csharp-legacy-formatted UUID
|
445
|
+
def from_uuid_old_to_csharp_legacy_uuid(hex)
|
446
|
+
hex.sub(/\A(..)(..)(..)(..)(..)(..)(..)(..)(.{16})\z/, '\4\3\2\1\6\5\8\7\9')
|
447
|
+
end
|
448
|
+
|
449
|
+
# Converts a UUID-old object to a java-legacy representation.
|
450
|
+
#
|
451
|
+
# @param [ String ] hex The hexadecimal string to convert
|
452
|
+
#
|
453
|
+
# @return [ String ] the java-legacy-formatted UUID
|
454
|
+
def from_uuid_old_to_java_legacy_uuid(hex)
|
455
|
+
hex.sub(/\A(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)\z/) do
|
456
|
+
(::Regexp.last_match[1..8].reverse + ::Regexp.last_match[9..16].reverse).join
|
367
457
|
end
|
368
458
|
end
|
369
459
|
|
370
|
-
|
460
|
+
# Converts a UUID-old object to a python-legacy representation.
|
461
|
+
#
|
462
|
+
# @param [ String ] hex The hexadecimal string to convert
|
463
|
+
#
|
464
|
+
# @return [ String ] the python-legacy-formatted UUID
|
465
|
+
def from_uuid_old_to_python_legacy_uuid(hex)
|
466
|
+
hex
|
467
|
+
end
|
371
468
|
|
372
469
|
# Validate the provided type is a valid type.
|
373
470
|
#
|
@@ -376,13 +473,58 @@ module BSON
|
|
376
473
|
# @example Validate the type.
|
377
474
|
# binary.validate_type!(:user)
|
378
475
|
#
|
379
|
-
# @param [
|
476
|
+
# @param [ Symbol | String | Integer ] type The provided type.
|
477
|
+
#
|
478
|
+
# @return [ Symbol ] the symbolic type corresponding to the argument.
|
380
479
|
#
|
381
|
-
# @raise [
|
480
|
+
# @raise [ BSON::Error::InvalidBinaryType ] The the type is invalid.
|
382
481
|
#
|
383
482
|
# @since 2.0.0
|
384
483
|
def validate_type!(type)
|
385
|
-
|
484
|
+
case type
|
485
|
+
when Integer then validate_integer_type!(type)
|
486
|
+
when String
|
487
|
+
if type.length > 1
|
488
|
+
validate_symbol_type!(type.to_sym)
|
489
|
+
else
|
490
|
+
validate_integer_type!(type.bytes.first)
|
491
|
+
end
|
492
|
+
when Symbol then validate_symbol_type!(type)
|
493
|
+
else raise BSON::Error::InvalidBinaryType, type
|
494
|
+
end
|
495
|
+
end
|
496
|
+
|
497
|
+
# Test that the given integer type is valid.
|
498
|
+
#
|
499
|
+
# @param [ Integer ] type the provided type
|
500
|
+
#
|
501
|
+
# @return [ Symbol ] the symbolic type corresponding to the argument.
|
502
|
+
#
|
503
|
+
# @raise [ BSON::Error::InvalidBinaryType] if the type is invalid.
|
504
|
+
def validate_integer_type!(type)
|
505
|
+
@raw_type = type.chr.force_encoding('BINARY').freeze
|
506
|
+
|
507
|
+
if type < USER_SUBTYPE
|
508
|
+
raise BSON::Error::InvalidBinaryType, type unless TYPES.key?(@raw_type)
|
509
|
+
|
510
|
+
return TYPES[@raw_type]
|
511
|
+
end
|
512
|
+
|
513
|
+
:user
|
514
|
+
end
|
515
|
+
|
516
|
+
# Test that the given symbol type is valid.
|
517
|
+
#
|
518
|
+
# @param [ Symbol ] type the provided type
|
519
|
+
#
|
520
|
+
# @return [ Symbol ] the symbolic type corresponding to the argument.
|
521
|
+
#
|
522
|
+
# @raise [ BSON::Error::InvalidBinaryType] if the type is invalid.
|
523
|
+
def validate_symbol_type!(type)
|
524
|
+
raise BSON::Error::InvalidBinaryType, type unless SUBTYPES.key?(type)
|
525
|
+
|
526
|
+
@raw_type = SUBTYPES[type]
|
527
|
+
type
|
386
528
|
end
|
387
529
|
|
388
530
|
# Register this type when the module is loaded.
|
data/lib/bson/boolean.rb
CHANGED
data/lib/bson/code.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");
|
@@ -48,27 +49,24 @@ module BSON
|
|
48
49
|
javascript == other.javascript
|
49
50
|
end
|
50
51
|
|
51
|
-
#
|
52
|
+
# Return a representation of the object for use in
|
53
|
+
# application-level JSON serialization. Since BSON::Code
|
54
|
+
# is used exclusively in BSON-related contexts, this
|
55
|
+
# method returns the canonical Extended JSON representation.
|
52
56
|
#
|
53
|
-
# @
|
54
|
-
|
55
|
-
#
|
56
|
-
# @return [ Hash ] The code as a JSON hash.
|
57
|
-
#
|
58
|
-
# @since 2.0.0
|
59
|
-
# @deprecated Use as_extended_json instead.
|
60
|
-
def as_json(*args)
|
57
|
+
# @return [ Hash ] The extended json representation.
|
58
|
+
def as_json(*_args)
|
61
59
|
as_extended_json
|
62
60
|
end
|
63
61
|
|
64
62
|
# Converts this object to a representation directly serializable to
|
65
|
-
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.
|
63
|
+
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
|
66
64
|
#
|
67
65
|
# @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
|
68
66
|
# (default is canonical extended JSON)
|
69
67
|
#
|
70
68
|
# @return [ Hash ] The extended json representation.
|
71
|
-
def as_extended_json(**
|
69
|
+
def as_extended_json(**_options)
|
72
70
|
{ "$code" => javascript }
|
73
71
|
end
|
74
72
|
|
@@ -94,7 +92,7 @@ module BSON
|
|
94
92
|
# @see http://bsonspec.org/#/specification
|
95
93
|
#
|
96
94
|
# @since 2.0.0
|
97
|
-
def to_bson(buffer = ByteBuffer.new
|
95
|
+
def to_bson(buffer = ByteBuffer.new)
|
98
96
|
buffer.put_string(javascript) # @todo: was formerly to_bson_string
|
99
97
|
end
|
100
98
|
|