bson 4.2.2 → 4.12.1
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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +25 -7
- data/Rakefile +16 -9
- data/ext/bson/{native-endian.h → bson-endian.h} +5 -99
- data/ext/bson/bson-native.h +125 -0
- data/ext/bson/bytebuf.c +133 -0
- data/ext/bson/endian.c +117 -0
- data/ext/bson/init.c +355 -0
- data/ext/bson/libbson-utf8.c +230 -0
- data/ext/bson/read.c +411 -0
- data/ext/bson/util.c +95 -0
- data/ext/bson/write.c +680 -0
- data/lib/bson.rb +6 -3
- data/lib/bson/active_support.rb +17 -0
- data/lib/bson/array.rb +57 -17
- data/lib/bson/binary.rb +185 -13
- data/lib/bson/boolean.rb +12 -3
- data/lib/bson/code.rb +16 -2
- data/lib/bson/code_with_scope.rb +32 -5
- data/lib/bson/config.rb +1 -1
- data/lib/bson/date.rb +12 -2
- data/lib/bson/date_time.rb +2 -2
- data/lib/bson/db_pointer.rb +110 -0
- data/lib/bson/decimal128.rb +17 -3
- data/lib/bson/decimal128/builder.rb +1 -1
- data/lib/bson/document.rb +152 -5
- data/lib/bson/environment.rb +2 -1
- data/lib/bson/error.rb +27 -0
- data/lib/bson/ext_json.rb +383 -0
- data/lib/bson/false_class.rb +1 -1
- data/lib/bson/float.rb +48 -2
- data/lib/bson/hash.rb +68 -17
- data/lib/bson/int32.rb +52 -13
- data/lib/bson/int64.rb +59 -15
- data/lib/bson/integer.rb +36 -2
- data/lib/bson/json.rb +1 -1
- data/lib/bson/max_key.rb +13 -1
- data/lib/bson/min_key.rb +13 -1
- data/lib/bson/nil_class.rb +4 -2
- data/lib/bson/object.rb +28 -1
- data/lib/bson/object_id.rb +16 -2
- data/lib/bson/open_struct.rb +1 -1
- data/lib/bson/regexp.rb +27 -4
- data/lib/bson/registry.rb +3 -3
- data/lib/bson/specialized.rb +4 -2
- data/lib/bson/string.rb +5 -3
- data/lib/bson/symbol.rb +99 -7
- data/lib/bson/time.rb +63 -4
- data/lib/bson/time_with_zone.rb +54 -0
- data/lib/bson/timestamp.rb +44 -6
- data/lib/bson/true_class.rb +1 -1
- data/lib/bson/undefined.rb +12 -1
- data/lib/bson/version.rb +2 -2
- data/spec/bson/array_spec.rb +18 -1
- data/spec/bson/binary_spec.rb +100 -3
- data/spec/bson/binary_uuid_spec.rb +189 -0
- data/spec/bson/boolean_spec.rb +1 -1
- data/spec/bson/byte_buffer_read_spec.rb +197 -0
- data/spec/bson/byte_buffer_spec.rb +121 -381
- data/spec/bson/byte_buffer_write_spec.rb +854 -0
- data/spec/bson/code_spec.rb +1 -1
- data/spec/bson/code_with_scope_spec.rb +1 -1
- data/spec/bson/date_spec.rb +1 -1
- data/spec/bson/date_time_spec.rb +54 -1
- data/spec/bson/decimal128_spec.rb +35 -35
- data/spec/bson/document_as_spec.rb +46 -0
- data/spec/bson/document_spec.rb +197 -30
- data/spec/bson/ext_json_parse_spec.rb +308 -0
- data/spec/bson/false_class_spec.rb +1 -1
- data/spec/bson/float_spec.rb +37 -1
- data/spec/bson/hash_as_spec.rb +57 -0
- data/spec/bson/hash_spec.rb +209 -1
- data/spec/bson/int32_spec.rb +180 -6
- data/spec/bson/int64_spec.rb +199 -6
- data/spec/bson/integer_spec.rb +29 -3
- data/spec/bson/json_spec.rb +1 -1
- data/spec/bson/max_key_spec.rb +1 -1
- data/spec/bson/min_key_spec.rb +1 -1
- data/spec/bson/nil_class_spec.rb +1 -1
- data/spec/bson/object_id_spec.rb +1 -1
- data/spec/bson/object_spec.rb +1 -1
- data/spec/bson/open_struct_spec.rb +1 -1
- data/spec/bson/raw_spec.rb +34 -2
- data/spec/bson/regexp_spec.rb +1 -1
- data/spec/bson/registry_spec.rb +1 -1
- data/spec/bson/string_spec.rb +19 -1
- data/spec/bson/symbol_raw_spec.rb +45 -0
- data/spec/bson/symbol_spec.rb +63 -3
- data/spec/bson/time_spec.rb +205 -2
- data/spec/bson/time_with_zone_spec.rb +68 -0
- data/spec/bson/timestamp_spec.rb +56 -1
- data/spec/bson/true_class_spec.rb +1 -1
- data/spec/bson/undefined_spec.rb +1 -1
- data/spec/bson_spec.rb +1 -1
- data/spec/{support → runners}/common_driver.rb +1 -1
- data/spec/runners/corpus.rb +185 -0
- data/spec/{support/corpus.rb → runners/corpus_legacy.rb} +41 -59
- data/spec/spec_helper.rb +40 -3
- data/spec/{bson/driver_bson_spec.rb → spec_tests/common_driver_spec.rb} +1 -0
- data/spec/{bson/corpus_spec.rb → spec_tests/corpus_legacy_spec.rb} +10 -7
- data/spec/spec_tests/corpus_spec.rb +124 -0
- data/spec/spec_tests/data/corpus/README.md +15 -0
- data/spec/spec_tests/data/corpus/array.json +49 -0
- data/spec/spec_tests/data/corpus/binary.json +113 -0
- data/spec/spec_tests/data/corpus/boolean.json +27 -0
- data/spec/spec_tests/data/corpus/code.json +67 -0
- data/spec/spec_tests/data/corpus/code_w_scope.json +78 -0
- data/spec/spec_tests/data/corpus/datetime.json +42 -0
- data/spec/spec_tests/data/corpus/dbpointer.json +56 -0
- data/spec/spec_tests/data/corpus/dbref.json +31 -0
- data/spec/spec_tests/data/corpus/decimal128-1.json +317 -0
- data/spec/spec_tests/data/corpus/decimal128-2.json +793 -0
- data/spec/spec_tests/data/corpus/decimal128-3.json +1771 -0
- data/spec/spec_tests/data/corpus/decimal128-4.json +117 -0
- data/spec/spec_tests/data/corpus/decimal128-5.json +402 -0
- data/spec/spec_tests/data/corpus/decimal128-6.json +119 -0
- data/spec/spec_tests/data/corpus/decimal128-7.json +323 -0
- data/spec/spec_tests/data/corpus/document.json +36 -0
- data/spec/spec_tests/data/corpus/double.json +87 -0
- data/spec/spec_tests/data/corpus/int32.json +43 -0
- data/spec/spec_tests/data/corpus/int64.json +43 -0
- data/spec/spec_tests/data/corpus/maxkey.json +12 -0
- data/spec/spec_tests/data/corpus/minkey.json +12 -0
- data/spec/spec_tests/data/corpus/multi-type-deprecated.json +15 -0
- data/spec/spec_tests/data/corpus/multi-type.json +11 -0
- data/spec/spec_tests/data/corpus/null.json +12 -0
- data/spec/spec_tests/data/corpus/oid.json +28 -0
- data/spec/spec_tests/data/corpus/regex.json +65 -0
- data/spec/spec_tests/data/corpus/string.json +72 -0
- data/spec/spec_tests/data/corpus/symbol.json +80 -0
- data/spec/spec_tests/data/corpus/timestamp.json +34 -0
- data/spec/spec_tests/data/corpus/top.json +236 -0
- data/spec/spec_tests/data/corpus/undefined.json +15 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/array.json +8 -2
- data/spec/{support/corpus-tests/failures → spec_tests/data/corpus_legacy}/binary.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/boolean.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/code.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/code_w_scope.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/document.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/double.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/datetime.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/dbpointer.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/int64.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/symbol.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/int32.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/maxkey.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/minkey.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/null.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/oid.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/regex.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/string.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/timestamp.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/top.json +0 -0
- data/spec/{support/corpus-tests/failures → spec_tests/data/corpus_legacy}/undefined.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-1.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-2.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-3.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-4.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-5.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-6.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-7.json +0 -0
- data/spec/support/shared_examples.rb +3 -5
- data/spec/support/spec_config.rb +16 -0
- data/spec/support/utils.rb +10 -0
- metadata +227 -124
- metadata.gz.sig +0 -0
- data/ext/bson/bson_native.c +0 -762
data/lib/bson/code.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009-
|
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.
|
@@ -55,7 +55,19 @@ module BSON
|
|
55
55
|
# @return [ Hash ] The code as a JSON hash.
|
56
56
|
#
|
57
57
|
# @since 2.0.0
|
58
|
+
# @deprecated Use as_extended_json instead.
|
58
59
|
def as_json(*args)
|
60
|
+
as_extended_json
|
61
|
+
end
|
62
|
+
|
63
|
+
# Converts this object to a representation directly serializable to
|
64
|
+
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
|
65
|
+
#
|
66
|
+
# @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
|
67
|
+
# (default is canonical extended JSON)
|
68
|
+
#
|
69
|
+
# @return [ Hash ] The extended json representation.
|
70
|
+
def as_extended_json(**options)
|
59
71
|
{ "$code" => javascript }
|
60
72
|
end
|
61
73
|
|
@@ -89,12 +101,14 @@ module BSON
|
|
89
101
|
#
|
90
102
|
# @param [ ByteBuffer ] buffer The byte buffer.
|
91
103
|
#
|
104
|
+
# @option options [ nil | :bson ] :mode Decoding mode to use.
|
105
|
+
#
|
92
106
|
# @return [ TrueClass, FalseClass ] The decoded code.
|
93
107
|
#
|
94
108
|
# @see http://bsonspec.org/#/specification
|
95
109
|
#
|
96
110
|
# @since 2.0.0
|
97
|
-
def self.from_bson(buffer)
|
111
|
+
def self.from_bson(buffer, **options)
|
98
112
|
new(buffer.get_string)
|
99
113
|
end
|
100
114
|
|
data/lib/bson/code_with_scope.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009-
|
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.
|
@@ -59,8 +59,20 @@ module BSON
|
|
59
59
|
# @return [ Hash ] The code with scope as a JSON hash.
|
60
60
|
#
|
61
61
|
# @since 2.0.0
|
62
|
+
# @deprecated Use as_extended_json instead.
|
62
63
|
def as_json(*args)
|
63
|
-
|
64
|
+
as_extended_json
|
65
|
+
end
|
66
|
+
|
67
|
+
# Converts this object to a representation directly serializable to
|
68
|
+
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
|
69
|
+
#
|
70
|
+
# @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
|
71
|
+
# (default is canonical extended JSON)
|
72
|
+
#
|
73
|
+
# @return [ Hash ] The extended json representation.
|
74
|
+
def as_extended_json(**options)
|
75
|
+
{ "$code" => javascript, "$scope" => scope.as_extended_json(**options) }
|
64
76
|
end
|
65
77
|
|
66
78
|
# Instantiate the new code with scope.
|
@@ -99,14 +111,29 @@ module BSON
|
|
99
111
|
#
|
100
112
|
# @param [ ByteBuffer ] buffer The byte buffer.
|
101
113
|
#
|
114
|
+
# @option options [ nil | :bson ] :mode Decoding mode to use.
|
115
|
+
#
|
102
116
|
# @return [ TrueClass, FalseClass ] The decoded code with scope.
|
103
117
|
#
|
104
118
|
# @see http://bsonspec.org/#/specification
|
105
119
|
#
|
106
120
|
# @since 2.0.0
|
107
|
-
def self.from_bson(buffer)
|
108
|
-
|
109
|
-
|
121
|
+
def self.from_bson(buffer, **options)
|
122
|
+
# Code with scope has a length (?) field which is not needed for
|
123
|
+
# decoding, but spec tests want this field validated.
|
124
|
+
start_position = buffer.read_position
|
125
|
+
length = buffer.get_int32
|
126
|
+
javascript = buffer.get_string
|
127
|
+
scope = if options.empty?
|
128
|
+
::Hash.from_bson(buffer)
|
129
|
+
else
|
130
|
+
::Hash.from_bson(buffer, **options)
|
131
|
+
end
|
132
|
+
read_bytes = buffer.read_position - start_position
|
133
|
+
if read_bytes != length
|
134
|
+
raise Error::BSONDecodeError, "CodeWithScope invalid: claimed length #{length}, actual length #{read_bytes}"
|
135
|
+
end
|
136
|
+
new(javascript, scope)
|
110
137
|
end
|
111
138
|
|
112
139
|
# Register this type when the module is loaded.
|
data/lib/bson/config.rb
CHANGED
data/lib/bson/date.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009-
|
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.
|
@@ -16,6 +16,16 @@ require 'date'
|
|
16
16
|
|
17
17
|
module BSON
|
18
18
|
|
19
|
+
# Julian day of Date 1970-01-01 - UNIX timestamp reference.
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
DATE_REFERENCE = ::Date.new(1970, 1, 1).jd
|
23
|
+
|
24
|
+
# Number of miliseconds in a day.
|
25
|
+
#
|
26
|
+
# @api private
|
27
|
+
MILLISECONDS_IN_DAY = 60 * 60 * 24 * 1_000
|
28
|
+
|
19
29
|
# Injects behaviour for encoding date values to raw bytes as specified by
|
20
30
|
# the BSON spec for time.
|
21
31
|
#
|
@@ -35,7 +45,7 @@ module BSON
|
|
35
45
|
#
|
36
46
|
# @since 2.1.0
|
37
47
|
def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
|
38
|
-
|
48
|
+
buffer.put_int64((jd - DATE_REFERENCE) * MILLISECONDS_IN_DAY)
|
39
49
|
end
|
40
50
|
|
41
51
|
# Get the BSON type for the date.
|
data/lib/bson/date_time.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009-
|
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.
|
@@ -35,7 +35,7 @@ module BSON
|
|
35
35
|
#
|
36
36
|
# @since 2.1.0
|
37
37
|
def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
|
38
|
-
to_time.to_bson(buffer)
|
38
|
+
gregorian.to_time.to_bson(buffer)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# Copyright (C) 2020 MongoDB Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module BSON
|
16
|
+
|
17
|
+
# Injects behaviour for encoding and decoding DBPointer values to and from
|
18
|
+
# raw bytes as specified by the BSON spec.
|
19
|
+
#
|
20
|
+
# @see http://bsonspec.org/#/specification
|
21
|
+
class DbPointer
|
22
|
+
include JSON
|
23
|
+
|
24
|
+
# A DBPointer is type 0x0C in the BSON spec.
|
25
|
+
BSON_TYPE = 0x0C.chr.force_encoding(BINARY).freeze
|
26
|
+
|
27
|
+
# Create a new DBPointer object.
|
28
|
+
#
|
29
|
+
# @param [ String ] ref The database collection name.
|
30
|
+
# @param [ BSON::ObjectId ] id The DBPointer id.
|
31
|
+
def initialize(ref, id)
|
32
|
+
@ref = ref
|
33
|
+
@id = id
|
34
|
+
end
|
35
|
+
|
36
|
+
# Return the collection name.
|
37
|
+
#
|
38
|
+
# @return [ String ] The database collection name.
|
39
|
+
attr_reader :ref
|
40
|
+
|
41
|
+
# Return the DbPointer's id.
|
42
|
+
#
|
43
|
+
# @return [ BSON::ObjectId ] The id of the DbPointer instance
|
44
|
+
attr_reader :id
|
45
|
+
|
46
|
+
# Determine if this DBPointer object is equal to another object.
|
47
|
+
#
|
48
|
+
# @param [ Object ] other The object to compare against.
|
49
|
+
#
|
50
|
+
# @return [ true | false ] If the objects are equal
|
51
|
+
def ==(other)
|
52
|
+
return false unless other.is_a?(DbPointer)
|
53
|
+
ref == other.ref && id == other.id
|
54
|
+
end
|
55
|
+
|
56
|
+
# Get the DBPointer as JSON hash data
|
57
|
+
#
|
58
|
+
# @return [ Hash ] The DBPointer as a JSON hash.
|
59
|
+
#
|
60
|
+
# @deprecated Use as_extended_json instead.
|
61
|
+
def as_json(*args)
|
62
|
+
as_extended_json
|
63
|
+
end
|
64
|
+
|
65
|
+
# Converts this object to a representation directly serializable to
|
66
|
+
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
|
67
|
+
#
|
68
|
+
# @option options [ true | false ] :relaxed Whether to produce relaxed
|
69
|
+
# extended JSON representation.
|
70
|
+
#
|
71
|
+
# @return [ Hash ] The extended json representation.
|
72
|
+
def as_extended_json(**options)
|
73
|
+
{'$dbPointer' => { "$ref" => ref, '$id' => id.as_extended_json }}
|
74
|
+
end
|
75
|
+
|
76
|
+
# Encode the DBPointer.
|
77
|
+
#
|
78
|
+
# @return [ BSON::ByteBuffer ] The buffer with the encoded object.
|
79
|
+
#
|
80
|
+
# @see http://bsonspec.org/#/specification
|
81
|
+
def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
|
82
|
+
buffer.put_string(ref)
|
83
|
+
id.to_bson(buffer, validating_keys)
|
84
|
+
buffer
|
85
|
+
end
|
86
|
+
|
87
|
+
# Deserialize a DBPointer from BSON.
|
88
|
+
#
|
89
|
+
# @param [ ByteBuffer ] buffer The byte buffer.
|
90
|
+
# @param [ Hash ] options
|
91
|
+
#
|
92
|
+
# @option options [ nil | :bson ] :mode Decoding mode to use.
|
93
|
+
#
|
94
|
+
# @return [ BSON::DbPointer ] The decoded DBPointer.
|
95
|
+
#
|
96
|
+
# @see http://bsonspec.org/#/specification
|
97
|
+
def self.from_bson(buffer, **options)
|
98
|
+
ref = buffer.get_string
|
99
|
+
id = if options.empty?
|
100
|
+
ObjectId.from_bson(buffer)
|
101
|
+
else
|
102
|
+
ObjectId.from_bson(buffer, **options)
|
103
|
+
end
|
104
|
+
new(ref, id)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Register this type when the module is loaded.
|
108
|
+
Registry.register(BSON_TYPE, self)
|
109
|
+
end
|
110
|
+
end
|
data/lib/bson/decimal128.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2016 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.
|
@@ -63,7 +63,19 @@ module BSON
|
|
63
63
|
# @return [ Hash ] The number as a JSON hash.
|
64
64
|
#
|
65
65
|
# @since 4.2.0
|
66
|
+
# @deprecated Use as_extended_json instead.
|
66
67
|
def as_json(*args)
|
68
|
+
as_extended_json
|
69
|
+
end
|
70
|
+
|
71
|
+
# Converts this object to a representation directly serializable to
|
72
|
+
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
|
73
|
+
#
|
74
|
+
# @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
|
75
|
+
# (default is canonical extended JSON)
|
76
|
+
#
|
77
|
+
# @return [ Hash ] The extended json representation.
|
78
|
+
def as_extended_json(**options)
|
67
79
|
{ EXTENDED_JSON_KEY => to_s }
|
68
80
|
end
|
69
81
|
|
@@ -178,7 +190,7 @@ module BSON
|
|
178
190
|
#
|
179
191
|
# @since 4.2.0
|
180
192
|
def to_big_decimal
|
181
|
-
@big_decimal ||= BigDecimal
|
193
|
+
@big_decimal ||= BigDecimal(to_s)
|
182
194
|
end
|
183
195
|
|
184
196
|
private
|
@@ -197,10 +209,12 @@ module BSON
|
|
197
209
|
#
|
198
210
|
# @param [ ByteBuffer ] buffer The byte buffer.
|
199
211
|
#
|
212
|
+
# @option options [ nil | :bson ] :mode Decoding mode to use.
|
213
|
+
#
|
200
214
|
# @return [ BSON::Decimal128 ] The decimal object.
|
201
215
|
#
|
202
216
|
# @since 4.2.0
|
203
|
-
def from_bson(buffer)
|
217
|
+
def from_bson(buffer, **options)
|
204
218
|
from_bits(*buffer.get_decimal128_bytes.unpack('Q<*'))
|
205
219
|
end
|
206
220
|
|
data/lib/bson/document.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009-
|
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.
|
@@ -35,8 +35,43 @@ module BSON
|
|
35
35
|
class Document < ::Hash
|
36
36
|
|
37
37
|
# Get a value from the document for the provided key. Can use string or
|
38
|
-
# symbol access,
|
39
|
-
#
|
38
|
+
# symbol access, with string access being the faster of the two.
|
39
|
+
#
|
40
|
+
# @overload fetch(key)
|
41
|
+
# Returns a value from the hash for the given key. If the key does
|
42
|
+
# not exist, raises KeyError exception.
|
43
|
+
#
|
44
|
+
# @overload fetch(key, default)
|
45
|
+
# Returns a value from the hash for the given key. If the key does not
|
46
|
+
# exist, returns *default*.
|
47
|
+
#
|
48
|
+
# @overload fetch(key, &block)
|
49
|
+
# Returns a value from the hash for the given key. If the key does not
|
50
|
+
# exist, returns the value of the block called with the key.
|
51
|
+
#
|
52
|
+
# @example Get an element for the key.
|
53
|
+
# document.fetch("field")
|
54
|
+
#
|
55
|
+
# @example Get an element for the key by symbol with a default.
|
56
|
+
# document.fetch(:field, 'foo')
|
57
|
+
#
|
58
|
+
# @example Get an element for the key by symbol with a block default.
|
59
|
+
# document.fetch(:field) { |key| key.upcase }
|
60
|
+
#
|
61
|
+
# @param [ String, Symbol ] key The key to look up.
|
62
|
+
# @param [ Object ] default Returned value if key does not exist.
|
63
|
+
# @yield [key] Block returning default value for the given key.
|
64
|
+
#
|
65
|
+
# @return [ Object ] The found value. Raises KeyError if none found.
|
66
|
+
#
|
67
|
+
# @since 4.4.0
|
68
|
+
def fetch(key, *args, &block)
|
69
|
+
key = convert_key(key)
|
70
|
+
super(key, *args, &block)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Get a value from the document for the provided key. Can use string or
|
74
|
+
# symbol access, with string access being the faster of the two.
|
40
75
|
#
|
41
76
|
# @example Get an element for the key.
|
42
77
|
# document["field"]
|
@@ -44,7 +79,7 @@ module BSON
|
|
44
79
|
# @example Get an element for the key by symbol.
|
45
80
|
# document[:field]
|
46
81
|
#
|
47
|
-
# @param [ String, Symbol ] key The key to
|
82
|
+
# @param [ String, Symbol ] key The key to look up.
|
48
83
|
#
|
49
84
|
# @return [ Object ] The found value, or nil if none found.
|
50
85
|
#
|
@@ -53,7 +88,49 @@ module BSON
|
|
53
88
|
super(convert_key(key))
|
54
89
|
end
|
55
90
|
|
56
|
-
#
|
91
|
+
# Stores a key-value pair in the current document.
|
92
|
+
#
|
93
|
+
# Since BSON documents provide deep indifferent access (both strings and
|
94
|
+
# symbols are accepted as keys, recursively), the value may be converted
|
95
|
+
# to facilitate indifferent access. This conversion is performed for
|
96
|
+
# built-in Array and Hash classes, and other classes can override
|
97
|
+
# +to_bson_normalized_value+ method to provide custom conversion logic.
|
98
|
+
# For example:
|
99
|
+
#
|
100
|
+
# doc = BSON::Document.new
|
101
|
+
# doc[:a] = {b: {c: 'd'}}
|
102
|
+
# doc['a']['b']['c']
|
103
|
+
# # => "d"
|
104
|
+
#
|
105
|
+
# Note that due to this conversion, the object that is stored in the
|
106
|
+
# receiver Document may be different from the object supplied as the
|
107
|
+
# right hand side of the assignment. In Ruby, the result of assignment
|
108
|
+
# is the right hand side, not the return value of []= method.
|
109
|
+
# Because of this, modifying the result of assignment generally does not
|
110
|
+
# work as intended:
|
111
|
+
#
|
112
|
+
# doc = BSON::Document.new
|
113
|
+
# foo = (doc[:a] = {b: {c: 'd'}})
|
114
|
+
# # foo is original Hash with symbol keys
|
115
|
+
# foo['test'] = 'test'
|
116
|
+
# # doc is not modified
|
117
|
+
# doc
|
118
|
+
# # => {"a"=>{"b"=>{"c"=>"d"}}}
|
119
|
+
#
|
120
|
+
# This behavior can be encountered when defaulting document contents with
|
121
|
+
# []= in a method, such as:
|
122
|
+
#
|
123
|
+
# def foo
|
124
|
+
# # @doc is a BSON::Document
|
125
|
+
# @doc[:foo] ||= calculation
|
126
|
+
# end
|
127
|
+
#
|
128
|
+
# The above method should be written as follows to allow chaining:
|
129
|
+
#
|
130
|
+
# def foo
|
131
|
+
# # @doc is a BSON::Document
|
132
|
+
# @doc[:foo] ||= calculation and @doc[:foo]
|
133
|
+
# end
|
57
134
|
#
|
58
135
|
# @example Set a value on the document.
|
59
136
|
# document[:test] = "value"
|
@@ -172,6 +249,76 @@ module BSON
|
|
172
249
|
|
173
250
|
alias :update :merge!
|
174
251
|
|
252
|
+
if instance_methods.include?(:dig)
|
253
|
+
# Retrieves the value object corresponding to the each key objects repeatedly.
|
254
|
+
# Will normalize symbol keys into strings.
|
255
|
+
#
|
256
|
+
# @example Get value from nested sub-documents, handling missing levels.
|
257
|
+
# document # => { :key1 => { "key2" => "value"}}
|
258
|
+
# document.dig(:key1, :key2) # => "value"
|
259
|
+
# document.dig("key1", "key2") # => "value"
|
260
|
+
# document.dig("foo", "key2") # => nil
|
261
|
+
#
|
262
|
+
# @param [ Array<String, Symbol> ] *keys Keys, which constitute a "path" to the nested value.
|
263
|
+
#
|
264
|
+
# @return [ Object, NilClass ] The requested value or nil.
|
265
|
+
#
|
266
|
+
# @since 3.0.0
|
267
|
+
def dig(*keys)
|
268
|
+
super(*keys.map{|key| convert_key(key)})
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
# Slices a document to include only the given keys.
|
273
|
+
# Will normalize symbol keys into strings.
|
274
|
+
# (this method is backported from ActiveSupport::Hash)
|
275
|
+
#
|
276
|
+
# @example Get a document/hash with only the `name` and `age` fields present
|
277
|
+
# document # => { _id: <ObjectId>, :name => "John", :age => 30, :location => "Earth" }
|
278
|
+
# document.slice(:name, 'age') # => { "name": "John", "age" => 30 }
|
279
|
+
# document.slice('name') # => { "name" => "John" }
|
280
|
+
# document.slice(:foo) # => {}
|
281
|
+
#
|
282
|
+
# @param [ Array<String, Symbol> ] *keys Keys, that will be kept in the resulting document
|
283
|
+
#
|
284
|
+
# @return [ BSON::Document ] The document with only the selected keys
|
285
|
+
#
|
286
|
+
# @since 4.3.1
|
287
|
+
def slice(*keys)
|
288
|
+
keys.each_with_object(self.class.new) do |key, hash|
|
289
|
+
if key?(key)
|
290
|
+
hash[key] = self[key]
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
# Returns a new document consisting of the current document minus the
|
296
|
+
# specified keys.
|
297
|
+
#
|
298
|
+
# The keys to be removed can be specified as either strings or symbols.
|
299
|
+
#
|
300
|
+
# @example Get a document/hash with only the `name` and `age` fields removed
|
301
|
+
# document # => { _id: <ObjectId>, :name => 'John', :age => 30, :location => 'Earth' }
|
302
|
+
# document.except(:name, 'age') # => { _id: <ObjectId>, location: 'Earth' }
|
303
|
+
#
|
304
|
+
# @param [ Array<String, Symbol> ] *keys Keys, that will be removed in the resulting document
|
305
|
+
#
|
306
|
+
# @return [ BSON::Document ] The document with the specified keys removed.
|
307
|
+
#
|
308
|
+
# @note This method is always defined, even if Hash already contains a
|
309
|
+
# definition of #except, because ActiveSupport unconditionally defines
|
310
|
+
# its version of #except which doesn't work for BSON::Document which
|
311
|
+
# causes problems if ActiveSupport is loaded after bson-ruby is.
|
312
|
+
def except(*keys)
|
313
|
+
copy = dup
|
314
|
+
keys.each {|key| copy.delete(key)}
|
315
|
+
copy
|
316
|
+
end
|
317
|
+
|
318
|
+
def symbolize_keys!
|
319
|
+
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'
|
320
|
+
end
|
321
|
+
|
175
322
|
private
|
176
323
|
|
177
324
|
def convert_key(key)
|