bson 4.9.0 → 4.15.0
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
- checksums.yaml.gz.sig +0 -0
- data/README.md +15 -6
- data/ext/bson/bson-native.h +4 -0
- data/ext/bson/init.c +75 -23
- data/ext/bson/read.c +63 -11
- data/ext/bson/write.c +42 -3
- data/lib/bson/active_support.rb +1 -0
- data/lib/bson/array.rb +5 -1
- data/lib/bson/big_decimal.rb +67 -0
- data/lib/bson/binary.rb +8 -5
- data/lib/bson/boolean.rb +2 -1
- data/lib/bson/code.rb +2 -1
- data/lib/bson/code_with_scope.rb +2 -1
- data/lib/bson/config.rb +1 -0
- data/lib/bson/date.rb +1 -0
- data/lib/bson/date_time.rb +2 -1
- data/lib/bson/db_pointer.rb +2 -1
- data/lib/bson/dbref.rb +152 -0
- data/lib/bson/decimal128/builder.rb +27 -20
- data/lib/bson/decimal128.rb +39 -14
- data/lib/bson/document.rb +61 -18
- data/lib/bson/environment.rb +1 -0
- data/lib/bson/error.rb +13 -0
- data/lib/bson/ext_json.rb +24 -11
- data/lib/bson/false_class.rb +2 -1
- data/lib/bson/float.rb +21 -32
- data/lib/bson/hash.rb +18 -6
- data/lib/bson/int32.rb +3 -2
- data/lib/bson/int64.rb +3 -2
- data/lib/bson/integer.rb +3 -2
- data/lib/bson/json.rb +1 -0
- data/lib/bson/max_key.rb +3 -2
- data/lib/bson/min_key.rb +3 -2
- data/lib/bson/nil_class.rb +2 -1
- data/lib/bson/object.rb +1 -0
- data/lib/bson/object_id.rb +4 -3
- data/lib/bson/open_struct.rb +1 -0
- data/lib/bson/regexp.rb +24 -7
- data/lib/bson/registry.rb +1 -0
- data/lib/bson/specialized.rb +1 -0
- data/lib/bson/string.rb +3 -2
- data/lib/bson/symbol.rb +2 -1
- data/lib/bson/time.rb +4 -3
- data/lib/bson/time_with_zone.rb +1 -0
- data/lib/bson/timestamp.rb +7 -6
- data/lib/bson/true_class.rb +2 -1
- data/lib/bson/undefined.rb +2 -1
- data/lib/bson/version.rb +2 -1
- data/lib/bson.rb +8 -5
- data/spec/README.md +14 -0
- data/spec/bson/array_spec.rb +17 -0
- data/spec/bson/big_decimal_spec.rb +316 -0
- data/spec/bson/binary_spec.rb +1 -1
- data/spec/bson/binary_uuid_spec.rb +12 -0
- data/spec/bson/byte_buffer_read_spec.rb +59 -3
- data/spec/bson/byte_buffer_spec.rb +129 -6
- data/spec/bson/byte_buffer_write_spec.rb +96 -0
- data/spec/bson/date_time_spec.rb +53 -0
- data/spec/bson/dbref_legacy_spec.rb +169 -0
- data/spec/bson/dbref_spec.rb +487 -0
- data/spec/bson/decimal128_spec.rb +231 -0
- data/spec/bson/document_as_spec.rb +46 -0
- data/spec/bson/document_spec.rb +43 -1
- data/spec/bson/ext_json_parse_spec.rb +37 -0
- data/spec/bson/hash_as_spec.rb +57 -0
- data/spec/bson/hash_spec.rb +105 -0
- data/spec/bson/int64_spec.rb +4 -24
- data/spec/bson/raw_spec.rb +18 -1
- data/spec/bson/regexp_spec.rb +52 -0
- data/spec/runners/common_driver.rb +1 -1
- data/spec/shared/LICENSE +20 -0
- data/spec/shared/bin/get-mongodb-download-url +17 -0
- data/spec/shared/bin/s3-copy +45 -0
- data/spec/shared/bin/s3-upload +69 -0
- data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
- data/spec/shared/lib/mrss/cluster_config.rb +231 -0
- data/spec/shared/lib/mrss/constraints.rb +386 -0
- data/spec/shared/lib/mrss/docker_runner.rb +271 -0
- data/spec/shared/lib/mrss/event_subscriber.rb +200 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +191 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +120 -0
- data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
- data/spec/shared/lib/mrss/utils.rb +15 -0
- data/spec/shared/share/Dockerfile.erb +338 -0
- data/spec/shared/share/haproxy-1.conf +16 -0
- data/spec/shared/share/haproxy-2.conf +17 -0
- data/spec/shared/shlib/distro.sh +74 -0
- data/spec/shared/shlib/server.sh +367 -0
- data/spec/shared/shlib/set_env.sh +131 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/spec_tests/common_driver_spec.rb +2 -1
- data/spec/spec_tests/data/corpus/binary.json +33 -0
- data/spec/spec_tests/data/corpus/dbref.json +21 -1
- data/spec/spec_tests/data/corpus/document.json +4 -0
- data/spec/spec_tests/data/corpus/regex.json +2 -2
- data/spec/spec_tests/data/corpus/timestamp.json +10 -0
- data/spec/spec_tests/data/corpus/top.json +23 -12
- data/spec/support/spec_config.rb +8 -1
- data.tar.gz.sig +0 -0
- metadata +168 -93
- metadata.gz.sig +1 -0
data/lib/bson/binary.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Copyright (C) 2009-2020 MongoDB Inc.
|
2
3
|
#
|
3
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -27,7 +28,7 @@ module BSON
|
|
27
28
|
# A binary is type 0x05 in the BSON spec.
|
28
29
|
#
|
29
30
|
# @since 2.0.0
|
30
|
-
BSON_TYPE = 5.chr
|
31
|
+
BSON_TYPE = ::String.new(5.chr, encoding: BINARY).freeze
|
31
32
|
|
32
33
|
# The mappings of subtypes to their single byte identifiers.
|
33
34
|
#
|
@@ -46,7 +47,8 @@ module BSON
|
|
46
47
|
:uuid => 4.chr,
|
47
48
|
:md5 => 5.chr,
|
48
49
|
:ciphertext => 6.chr,
|
49
|
-
:
|
50
|
+
:column => 7.chr,
|
51
|
+
:user => 128.chr,
|
50
52
|
}.freeze
|
51
53
|
|
52
54
|
# The mappings of single byte subtypes to their symbol counterparts.
|
@@ -169,7 +171,7 @@ module BSON
|
|
169
171
|
#
|
170
172
|
# @since 2.3.0
|
171
173
|
def inspect
|
172
|
-
"<BSON::Binary:0x#{object_id} type=#{type} data=0x#{data[0, 8].
|
174
|
+
"<BSON::Binary:0x#{object_id} type=#{type} data=0x#{data[0, 8].unpack1('H*')}...>"
|
173
175
|
end
|
174
176
|
|
175
177
|
# Returns a string representation of the UUID stored in this Binary.
|
@@ -207,7 +209,8 @@ module BSON
|
|
207
209
|
if representation && representation != :standard
|
208
210
|
raise ArgumentError, "Binary of type :uuid can only be stringified to :standard representation, requested: #{representation.inspect}"
|
209
211
|
end
|
210
|
-
|
212
|
+
|
213
|
+
data.split('').map { |n| '%02x' % n.ord }.join.sub(/\A(.{8})(.{4})(.{4})(.{4})(.{12})\z/, '\1-\2-\3-\4-\5')
|
211
214
|
when :uuid_old
|
212
215
|
if representation.nil?
|
213
216
|
raise ArgumentError, 'Representation must be specified for BSON::Binary objects of type :uuid_old'
|
@@ -229,7 +232,7 @@ module BSON
|
|
229
232
|
hex
|
230
233
|
else
|
231
234
|
raise ArgumentError, "Invalid representation: #{representation}"
|
232
|
-
end.sub(
|
235
|
+
end.sub(/\A(.{8})(.{4})(.{4})(.{4})(.{12})\z/, '\1-\2-\3-\4-\5')
|
233
236
|
else
|
234
237
|
raise TypeError, "The type of Binary must be :uuid or :uuid_old, this object is: #{type.inspect}"
|
235
238
|
end
|
data/lib/bson/boolean.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Copyright (C) 2009-2020 MongoDB Inc.
|
2
3
|
#
|
3
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -25,7 +26,7 @@ module BSON
|
|
25
26
|
# A boolean is type 0x08 in the BSON spec.
|
26
27
|
#
|
27
28
|
# @since 2.0.0
|
28
|
-
BSON_TYPE = 8.chr
|
29
|
+
BSON_TYPE = ::String.new(8.chr, encoding: BINARY).freeze
|
29
30
|
|
30
31
|
# Deserialize a boolean from BSON.
|
31
32
|
#
|
data/lib/bson/code.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Copyright (C) 2009-2020 MongoDB Inc.
|
2
3
|
#
|
3
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -25,7 +26,7 @@ module BSON
|
|
25
26
|
# A code is type 0x0D in the BSON spec.
|
26
27
|
#
|
27
28
|
# @since 2.0.0
|
28
|
-
BSON_TYPE = 13.chr
|
29
|
+
BSON_TYPE = ::String.new(13.chr, encoding: BINARY).freeze
|
29
30
|
|
30
31
|
# @!attribute javascript
|
31
32
|
# @return [ String ] The javascript code.
|
data/lib/bson/code_with_scope.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Copyright (C) 2009-2020 MongoDB Inc.
|
2
3
|
#
|
3
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -26,7 +27,7 @@ module BSON
|
|
26
27
|
# A code with scope is type 0x0F in the BSON spec.
|
27
28
|
#
|
28
29
|
# @since 2.0.0
|
29
|
-
BSON_TYPE = 15.chr
|
30
|
+
BSON_TYPE = ::String.new(15.chr, encoding: BINARY).freeze
|
30
31
|
|
31
32
|
# @!attribute javascript
|
32
33
|
# @return [ String ] The javascript code.
|
data/lib/bson/config.rb
CHANGED
data/lib/bson/date.rb
CHANGED
data/lib/bson/date_time.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Copyright (C) 2009-2020 MongoDB Inc.
|
2
3
|
#
|
3
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -35,7 +36,7 @@ module BSON
|
|
35
36
|
#
|
36
37
|
# @since 2.1.0
|
37
38
|
def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
|
38
|
-
to_time.to_bson(buffer)
|
39
|
+
gregorian.to_time.to_bson(buffer)
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
data/lib/bson/db_pointer.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Copyright (C) 2020 MongoDB Inc.
|
2
3
|
#
|
3
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -22,7 +23,7 @@ module BSON
|
|
22
23
|
include JSON
|
23
24
|
|
24
25
|
# A DBPointer is type 0x0C in the BSON spec.
|
25
|
-
BSON_TYPE = 0x0C.chr
|
26
|
+
BSON_TYPE = ::String.new(0x0C.chr, encoding: BINARY).freeze
|
26
27
|
|
27
28
|
# Create a new DBPointer object.
|
28
29
|
#
|
data/lib/bson/dbref.rb
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
# Copyright (C) 2015-2021 MongoDB Inc.
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the 'License');
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an 'AS IS' BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
module BSON
|
19
|
+
|
20
|
+
# Represents a DBRef document in the database.
|
21
|
+
class DBRef < Document
|
22
|
+
include JSON
|
23
|
+
|
24
|
+
# The constant for the collection reference field.
|
25
|
+
#
|
26
|
+
# @deprecated
|
27
|
+
COLLECTION = '$ref'.freeze
|
28
|
+
|
29
|
+
# The constant for the id field.
|
30
|
+
#
|
31
|
+
# @deprecated
|
32
|
+
ID = '$id'.freeze
|
33
|
+
|
34
|
+
# The constant for the database field.
|
35
|
+
#
|
36
|
+
# @deprecated
|
37
|
+
DATABASE = '$db'.freeze
|
38
|
+
|
39
|
+
# @return [ String ] collection The collection name.
|
40
|
+
def collection
|
41
|
+
self['$ref']
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [ BSON::ObjectId ] id The referenced document id.
|
45
|
+
def id
|
46
|
+
self['$id']
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [ String ] database The database name.
|
50
|
+
def database
|
51
|
+
self['$db']
|
52
|
+
end
|
53
|
+
|
54
|
+
# Get the DBRef as a JSON document
|
55
|
+
#
|
56
|
+
# @example Get the DBRef as a JSON hash.
|
57
|
+
# dbref.as_json
|
58
|
+
#
|
59
|
+
# @return [ Hash ] The max key as a JSON hash.
|
60
|
+
def as_json(*args)
|
61
|
+
{}.update(self)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Instantiate a new DBRef.
|
65
|
+
#
|
66
|
+
# @example Create the DBRef - hash API.
|
67
|
+
# BSON::DBRef.new({'$ref' => 'users', '$id' => id, '$db' => 'database'})
|
68
|
+
#
|
69
|
+
# @example Create the DBRef - legacy API.
|
70
|
+
# BSON::DBRef.new('users', id, 'database')
|
71
|
+
#
|
72
|
+
# @param [ Hash | String ] hash_or_collection The DBRef hash, when using
|
73
|
+
# the hash API. It must contain $ref and $id. When using the legacy API,
|
74
|
+
# this parameter must be a String containing the collection name.
|
75
|
+
# @param [ Object ] id The object id, when using the legacy API.
|
76
|
+
# @param [ String ] database The database name, when using the legacy API.
|
77
|
+
def initialize(hash_or_collection, id = nil, database = nil)
|
78
|
+
if hash_or_collection.is_a?(Hash)
|
79
|
+
hash = hash_or_collection
|
80
|
+
|
81
|
+
unless id.nil? && database.nil?
|
82
|
+
raise ArgumentError, 'When using the hash API, DBRef constructor accepts only one argument'
|
83
|
+
end
|
84
|
+
else
|
85
|
+
warn("BSON::DBRef constructor called with the legacy API - please use the hash API instead")
|
86
|
+
|
87
|
+
if id.nil?
|
88
|
+
raise ArgumentError, 'When using the legacy constructor API, id must be provided'
|
89
|
+
end
|
90
|
+
|
91
|
+
hash = {
|
92
|
+
:$ref => hash_or_collection,
|
93
|
+
:$id => id,
|
94
|
+
:$db => database,
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
hash = reorder_fields(hash)
|
99
|
+
%w($ref $id).each do |key|
|
100
|
+
unless hash[key]
|
101
|
+
raise ArgumentError, "DBRef must have #{key}: #{hash}"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
unless hash['$ref'].is_a?(String)
|
106
|
+
raise ArgumentError, "The value for key $ref must be a string, got: #{hash['$ref']}"
|
107
|
+
end
|
108
|
+
|
109
|
+
if db = hash['$db']
|
110
|
+
unless db.is_a?(String)
|
111
|
+
raise ArgumentError, "The value for key $db must be a string, got: #{hash['$db']}"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
super(hash)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Converts the DBRef to raw BSON.
|
119
|
+
#
|
120
|
+
# @example Convert the DBRef to raw BSON.
|
121
|
+
# dbref.to_bson
|
122
|
+
#
|
123
|
+
# @param [ BSON::ByteBuffer ] buffer The encoded BSON buffer to append to.
|
124
|
+
# @param [ true, false ] validating_keys Whether keys should be validated when serializing.
|
125
|
+
#
|
126
|
+
# @return [ BSON::ByteBuffer ] The buffer with the encoded object.
|
127
|
+
def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
|
128
|
+
as_json.to_bson(buffer, validating_keys)
|
129
|
+
end
|
130
|
+
|
131
|
+
private
|
132
|
+
|
133
|
+
# Reorder the fields of the given Hash to have $ref first, $id second,
|
134
|
+
# and $db third. The rest of the fields in the hash can come in any
|
135
|
+
# order after that.
|
136
|
+
#
|
137
|
+
# @param [ Hash ] hash The input hash. Must be a valid dbref.
|
138
|
+
#
|
139
|
+
# @return [ Hash ] The hash with it's fields reordered.
|
140
|
+
def reorder_fields(hash)
|
141
|
+
hash = BSON::Document.new(hash)
|
142
|
+
reordered = {}
|
143
|
+
reordered['$ref'] = hash.delete('$ref')
|
144
|
+
reordered['$id'] = hash.delete('$id')
|
145
|
+
if db = hash.delete('$db')
|
146
|
+
reordered['$db'] = db
|
147
|
+
end
|
148
|
+
|
149
|
+
reordered.update(hash)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Copyright (C) 2016-2020 MongoDB Inc.
|
2
3
|
#
|
3
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -26,27 +27,27 @@ module BSON
|
|
26
27
|
# Infinity mask.
|
27
28
|
#
|
28
29
|
# @since 4.2.0
|
29
|
-
INFINITY_MASK = 0x7800000000000000
|
30
|
+
INFINITY_MASK = 0x7800000000000000
|
30
31
|
|
31
32
|
# NaN mask.
|
32
33
|
#
|
33
34
|
# @since 4.2.0
|
34
|
-
NAN_MASK = 0x7c00000000000000
|
35
|
+
NAN_MASK = 0x7c00000000000000
|
35
36
|
|
36
37
|
# SNaN mask.
|
37
38
|
#
|
38
39
|
# @since 4.2.0
|
39
|
-
SNAN_MASK = (1 << 57)
|
40
|
+
SNAN_MASK = (1 << 57)
|
40
41
|
|
41
42
|
# Signed bit mask.
|
42
43
|
#
|
43
44
|
# @since 4.2.0
|
44
|
-
SIGN_BIT_MASK = (1 << 63)
|
45
|
+
SIGN_BIT_MASK = (1 << 63)
|
45
46
|
|
46
47
|
# The two highest bits of the 64 high order bits.
|
47
48
|
#
|
48
49
|
# @since 4.2.0
|
49
|
-
TWO_HIGHEST_BITS_SET = (3 << 61)
|
50
|
+
TWO_HIGHEST_BITS_SET = (3 << 61)
|
50
51
|
|
51
52
|
extend self
|
52
53
|
|
@@ -84,9 +85,13 @@ module BSON
|
|
84
85
|
private
|
85
86
|
|
86
87
|
def validate_range!(exponent, significand)
|
87
|
-
unless
|
88
|
+
unless valid_exponent?(exponent)
|
88
89
|
raise Decimal128::InvalidRange.new
|
89
90
|
end
|
91
|
+
|
92
|
+
unless valid_significand?(significand)
|
93
|
+
raise Decimal128::UnrepresentablePrecision.new
|
94
|
+
end
|
90
95
|
end
|
91
96
|
|
92
97
|
def valid_significand?(significand)
|
@@ -109,14 +114,14 @@ module BSON
|
|
109
114
|
# @return [ Regex ] A regex matching a NaN string.
|
110
115
|
#
|
111
116
|
# @since 4.2.0
|
112
|
-
NAN_REGEX = /^(\-)?(S)?NaN$/i
|
117
|
+
NAN_REGEX = /^(\-)?(S)?NaN$/i
|
113
118
|
|
114
119
|
# Regex matching a string representing positive or negative Infinity.
|
115
120
|
#
|
116
121
|
# @return [ Regex ] A regex matching a positive or negative Infinity string.
|
117
122
|
#
|
118
123
|
# @since 4.2.0
|
119
|
-
INFINITY_REGEX = /^(\+|\-)?Inf(inity)?$/i
|
124
|
+
INFINITY_REGEX = /^(\+|\-)?Inf(inity)?$/i
|
120
125
|
|
121
126
|
# Regex for the fraction, including leading zeros.
|
122
127
|
#
|
@@ -124,33 +129,33 @@ module BSON
|
|
124
129
|
# including leading zeros.
|
125
130
|
#
|
126
131
|
# @since 4.2.0
|
127
|
-
SIGNIFICAND_WITH_LEADING_ZEROS_REGEX = /(0*)(\d+)
|
132
|
+
SIGNIFICAND_WITH_LEADING_ZEROS_REGEX = /(0*)(\d+)/
|
128
133
|
|
129
134
|
# Regex for separating a negative sign from the significands.
|
130
135
|
#
|
131
136
|
# @return [ Regex ] The regex for separating a sign from significands.
|
132
137
|
#
|
133
138
|
# @since 4.2.0
|
134
|
-
SIGN_AND_DIGITS_REGEX = /^(\-)?(\S+)
|
139
|
+
SIGN_AND_DIGITS_REGEX = /^(\-)?(\S+)/
|
135
140
|
|
136
141
|
# Regex matching a scientific exponent.
|
137
142
|
#
|
138
143
|
# @return [ Regex ] A regex matching E, e, E+, e+.
|
139
144
|
#
|
140
145
|
# @since 4.2.0
|
141
|
-
SCIENTIFIC_EXPONENT_REGEX = /E\+?/i
|
146
|
+
SCIENTIFIC_EXPONENT_REGEX = /E\+?/i
|
142
147
|
|
143
148
|
# Regex for capturing trailing zeros.
|
144
149
|
#
|
145
150
|
# @since 4.2.0
|
146
|
-
TRAILING_ZEROS_REGEX = /[1-9]*(0+)
|
151
|
+
TRAILING_ZEROS_REGEX = /[1-9]*(0+)$/
|
147
152
|
|
148
153
|
# Regex for a valid decimal128 string format.
|
149
154
|
#
|
150
155
|
# @return [ Regex ] The regex for a valid decimal128 string.
|
151
156
|
#
|
152
157
|
# @since 4.2.0
|
153
|
-
VALID_DECIMAL128_STRING_REGEX = /^[\-\+]?(\d+(\.\d*)?|\.\d+)(E[\-\+]?\d+)?$/i
|
158
|
+
VALID_DECIMAL128_STRING_REGEX = /^[\-\+]?(\d+(\.\d*)?|\.\d+)(E[\-\+]?\d+)?$/i
|
154
159
|
|
155
160
|
# Initialize the FromString Builder object.
|
156
161
|
#
|
@@ -301,11 +306,11 @@ module BSON
|
|
301
306
|
|
302
307
|
def to_special_bits
|
303
308
|
case @big_decimal.sign
|
304
|
-
when BigDecimal::SIGN_POSITIVE_INFINITE
|
309
|
+
when ::BigDecimal::SIGN_POSITIVE_INFINITE
|
305
310
|
high = INFINITY_MASK
|
306
|
-
when BigDecimal::SIGN_NEGATIVE_INFINITE
|
311
|
+
when ::BigDecimal::SIGN_NEGATIVE_INFINITE
|
307
312
|
high = INFINITY_MASK | SIGN_BIT_MASK
|
308
|
-
when BigDecimal::SIGN_NaN
|
313
|
+
when ::BigDecimal::SIGN_NaN
|
309
314
|
high = NAN_MASK
|
310
315
|
end
|
311
316
|
[ 0, high ]
|
@@ -314,7 +319,7 @@ module BSON
|
|
314
319
|
def to_bits
|
315
320
|
sign, significand_str, base, exp = @big_decimal.split
|
316
321
|
exponent = @big_decimal.zero? ? 0 : exp - significand_str.length
|
317
|
-
is_negative = (sign == BigDecimal::SIGN_NEGATIVE_FINITE || sign == BigDecimal::SIGN_NEGATIVE_ZERO)
|
322
|
+
is_negative = (sign == ::BigDecimal::SIGN_NEGATIVE_FINITE || sign == ::BigDecimal::SIGN_NEGATIVE_ZERO)
|
318
323
|
Builder.parts_to_bits(significand_str.to_i,
|
319
324
|
exponent,
|
320
325
|
is_negative)
|
@@ -337,14 +342,14 @@ module BSON
|
|
337
342
|
# @return [ String ] The string representing NaN.
|
338
343
|
#
|
339
344
|
# @since 4.2.0
|
340
|
-
NAN_STRING = 'NaN'
|
345
|
+
NAN_STRING = 'NaN'
|
341
346
|
|
342
347
|
# String representing an Infinity value.
|
343
348
|
#
|
344
349
|
# @return [ String ] The string representing Infinity.
|
345
350
|
#
|
346
351
|
# @since 4.2.0
|
347
|
-
INFINITY_STRING = 'Infinity'
|
352
|
+
INFINITY_STRING = 'Infinity'
|
348
353
|
|
349
354
|
# Initialize the FromBigDecimal Builder object.
|
350
355
|
#
|
@@ -366,11 +371,13 @@ module BSON
|
|
366
371
|
#
|
367
372
|
# @return [ String ] The string representing the decimal128 object.
|
368
373
|
#
|
374
|
+
# @note The returned string may be frozen.
|
375
|
+
#
|
369
376
|
# @since 4.2.0
|
370
377
|
def string
|
371
378
|
return NAN_STRING if nan?
|
372
379
|
str = infinity? ? INFINITY_STRING : create_string
|
373
|
-
negative? ?
|
380
|
+
negative? ? "-#{str}" : str
|
374
381
|
end
|
375
382
|
|
376
383
|
private
|
data/lib/bson/decimal128.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Copyright (C) 2016-2020 MongoDB Inc.
|
2
3
|
#
|
3
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -19,36 +20,37 @@ module BSON
|
|
19
20
|
|
20
21
|
class Decimal128
|
21
22
|
include JSON
|
23
|
+
include Comparable
|
22
24
|
|
23
25
|
# A Decimal128 is type 0x13 in the BSON spec.
|
24
26
|
#
|
25
27
|
# @since 4.2.0
|
26
|
-
BSON_TYPE = 19.chr
|
28
|
+
BSON_TYPE = ::String.new(19.chr, encoding: BINARY).freeze
|
27
29
|
|
28
30
|
# Exponent offset.
|
29
31
|
#
|
30
32
|
# @since 4.2.0
|
31
|
-
EXPONENT_OFFSET = 6176
|
33
|
+
EXPONENT_OFFSET = 6176
|
32
34
|
|
33
35
|
# Minimum exponent.
|
34
36
|
#
|
35
37
|
# @since 4.2.0
|
36
|
-
MIN_EXPONENT = -6176
|
38
|
+
MIN_EXPONENT = -6176
|
37
39
|
|
38
40
|
# Maximum exponent.
|
39
41
|
#
|
40
42
|
# @since 4.2.0
|
41
|
-
MAX_EXPONENT = 6111
|
43
|
+
MAX_EXPONENT = 6111
|
42
44
|
|
43
45
|
# Maximum digits of precision.
|
44
46
|
#
|
45
47
|
# @since 4.2.0
|
46
|
-
MAX_DIGITS_OF_PRECISION = 34
|
48
|
+
MAX_DIGITS_OF_PRECISION = 34
|
47
49
|
|
48
50
|
# Key for this type when converted to extended json.
|
49
51
|
#
|
50
52
|
# @since 4.2.0
|
51
|
-
EXTENDED_JSON_KEY = "$numberDecimal"
|
53
|
+
EXTENDED_JSON_KEY = "$numberDecimal"
|
52
54
|
|
53
55
|
# The native type to which this object can be converted.
|
54
56
|
#
|
@@ -96,7 +98,16 @@ module BSON
|
|
96
98
|
end
|
97
99
|
alias :eql? :==
|
98
100
|
|
99
|
-
|
101
|
+
def <=>(other)
|
102
|
+
to_big_decimal <=> case other
|
103
|
+
when Decimal128
|
104
|
+
other.to_big_decimal
|
105
|
+
else
|
106
|
+
other
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Create a new Decimal128 from a string or a BigDecimal instance.
|
100
111
|
#
|
101
112
|
# @example Create a Decimal128 from a BigDecimal.
|
102
113
|
# Decimal128.new(big_decimal)
|
@@ -104,7 +115,7 @@ module BSON
|
|
104
115
|
# @param [ String, BigDecimal ] object The BigDecimal or String to use for
|
105
116
|
# instantiating a Decimal128.
|
106
117
|
#
|
107
|
-
# @raise [
|
118
|
+
# @raise [ InvalidArgument ] When argument is not a String or BigDecimal.
|
108
119
|
#
|
109
120
|
# @since 4.2.0
|
110
121
|
def initialize(object)
|
@@ -262,7 +273,7 @@ module BSON
|
|
262
273
|
# The custom error message for this error.
|
263
274
|
#
|
264
275
|
# @since 4.2.0
|
265
|
-
MESSAGE = 'A Decimal128 can only be created from a String or BigDecimal.'
|
276
|
+
MESSAGE = 'A Decimal128 can only be created from a String or BigDecimal.'
|
266
277
|
|
267
278
|
# Get the custom error message for the exception.
|
268
279
|
#
|
@@ -288,7 +299,7 @@ module BSON
|
|
288
299
|
# The custom error message for this error.
|
289
300
|
#
|
290
301
|
# @since 4.2.0
|
291
|
-
MESSAGE = 'Invalid string format for creating a Decimal128 object.'
|
302
|
+
MESSAGE = 'Invalid string format for creating a Decimal128 object.'
|
292
303
|
|
293
304
|
# Get the custom error message for the exception.
|
294
305
|
#
|
@@ -303,9 +314,7 @@ module BSON
|
|
303
314
|
end
|
304
315
|
end
|
305
316
|
|
306
|
-
# Raised when the exponent
|
307
|
-
#
|
308
|
-
# @api private
|
317
|
+
# Raised when the exponent is outside the valid range.
|
309
318
|
#
|
310
319
|
# @since 4.2.0
|
311
320
|
class InvalidRange < RuntimeError
|
@@ -313,7 +322,8 @@ module BSON
|
|
313
322
|
# The custom error message for this error.
|
314
323
|
#
|
315
324
|
# @since 4.2.0
|
316
|
-
|
325
|
+
# @deprecated
|
326
|
+
MESSAGE = 'Value out of range for Decimal128 representation.'
|
317
327
|
|
318
328
|
# Get the custom error message for the exception.
|
319
329
|
#
|
@@ -328,6 +338,21 @@ module BSON
|
|
328
338
|
end
|
329
339
|
end
|
330
340
|
|
341
|
+
# Raised when the significand provided is outside the valid range.
|
342
|
+
#
|
343
|
+
# @note This class derives from InvalidRange for backwards compatibility,
|
344
|
+
# however when RUBY-1806 is implemented it should be changed to derive
|
345
|
+
# from the base BSON exception class.
|
346
|
+
class UnrepresentablePrecision < InvalidRange
|
347
|
+
|
348
|
+
# Get the custom error message for the exception.
|
349
|
+
#
|
350
|
+
# @return [ String ] The error message.
|
351
|
+
def message
|
352
|
+
'The value contains too much precision for Decimal128 representation'
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
331
356
|
Registry.register(BSON_TYPE, self)
|
332
357
|
end
|
333
358
|
end
|
data/lib/bson/document.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Copyright (C) 2009-2020 MongoDB Inc.
|
2
3
|
#
|
3
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -269,27 +270,69 @@ module BSON
|
|
269
270
|
end
|
270
271
|
end
|
271
272
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
273
|
+
# Slices a document to include only the given keys.
|
274
|
+
# Will normalize symbol keys into strings.
|
275
|
+
# (this method is backported from ActiveSupport::Hash)
|
276
|
+
#
|
277
|
+
# @example Get a document/hash with only the `name` and `age` fields present
|
278
|
+
# document # => { _id: <ObjectId>, :name => "John", :age => 30, :location => "Earth" }
|
279
|
+
# document.slice(:name, 'age') # => { "name": "John", "age" => 30 }
|
280
|
+
# document.slice('name') # => { "name" => "John" }
|
281
|
+
# document.slice(:foo) # => {}
|
282
|
+
#
|
283
|
+
# @param [ Array<String, Symbol> ] *keys Keys, that will be kept in the resulting document
|
284
|
+
#
|
285
|
+
# @return [ BSON::Document ] The document with only the selected keys
|
286
|
+
#
|
287
|
+
# @since 4.3.1
|
288
|
+
def slice(*keys)
|
289
|
+
keys.each_with_object(self.class.new) do |key, hash|
|
290
|
+
if key?(key)
|
291
|
+
hash[key] = self[key]
|
292
|
+
end
|
290
293
|
end
|
291
294
|
end
|
292
295
|
|
296
|
+
# Returns a new document consisting of the current document minus the
|
297
|
+
# specified keys.
|
298
|
+
#
|
299
|
+
# The keys to be removed can be specified as either strings or symbols.
|
300
|
+
#
|
301
|
+
# @example Get a document/hash with only the `name` and `age` fields removed
|
302
|
+
# document # => { _id: <ObjectId>, :name => 'John', :age => 30, :location => 'Earth' }
|
303
|
+
# document.except(:name, 'age') # => { _id: <ObjectId>, location: 'Earth' }
|
304
|
+
#
|
305
|
+
# @param [ Array<String, Symbol> ] *keys Keys, that will be removed in the resulting document
|
306
|
+
#
|
307
|
+
# @return [ BSON::Document ] The document with the specified keys removed.
|
308
|
+
#
|
309
|
+
# @note This method is always defined, even if Hash already contains a
|
310
|
+
# definition of #except, because ActiveSupport unconditionally defines
|
311
|
+
# its version of #except which doesn't work for BSON::Document which
|
312
|
+
# causes problems if ActiveSupport is loaded after bson-ruby is.
|
313
|
+
def except(*keys)
|
314
|
+
copy = dup
|
315
|
+
keys.each {|key| copy.delete(key)}
|
316
|
+
copy
|
317
|
+
end
|
318
|
+
|
319
|
+
def symbolize_keys!
|
320
|
+
raise ArgumentError, 'symbolize_keys! is not supported on BSON::Document instances. Please convert the document to hash first (using #to_h), then call #symbolize_keys! on the Hash instance'
|
321
|
+
end
|
322
|
+
|
323
|
+
# Override the Hash implementation of to_bson_normalized_value.
|
324
|
+
#
|
325
|
+
# BSON::Document is already of the correct type and already provides
|
326
|
+
# indifferent access to keys, hence no further conversions are necessary.
|
327
|
+
#
|
328
|
+
# Attempting to perform Hash's conversion on Document instances converts
|
329
|
+
# DBRefs to Documents which is wrong.
|
330
|
+
#
|
331
|
+
# @return [ BSON::Document ] The normalized hash.
|
332
|
+
def to_bson_normalized_value
|
333
|
+
self
|
334
|
+
end
|
335
|
+
|
293
336
|
private
|
294
337
|
|
295
338
|
def convert_key(key)
|
data/lib/bson/environment.rb
CHANGED