bson 1.8.0 → 1.8.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bson might be problematic. Click here for more details.
- data/VERSION +1 -1
- data/bson.gemspec +4 -6
- data/lib/bson.rb +51 -35
- data/lib/bson/bson_java.rb +5 -3
- data/lib/bson/bson_ruby.rb +32 -31
- data/lib/bson/byte_buffer.rb +21 -58
- data/lib/bson/support/hash_with_indifferent_access.rb +168 -0
- data/lib/bson/types/binary.rb +4 -4
- data/lib/bson/types/object_id.rb +1 -1
- data/test/bson/bson_test.rb +1 -1
- data/test/bson/byte_buffer_test.rb +24 -26
- data/test/bson/hash_with_indifferent_access_test.rb +11 -1
- metadata +25 -37
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.8.
|
1
|
+
1.8.2
|
data/bson.gemspec
CHANGED
@@ -14,16 +14,14 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.files += Dir['lib/bson/**/*.rb']
|
15
15
|
|
16
16
|
if RUBY_PLATFORM =~ /java/
|
17
|
-
s.
|
18
|
-
s.
|
17
|
+
s.platform = 'java'
|
18
|
+
s.files += ['ext/jbson/target/jbson.jar', 'ext/jbson/lib/java-bson.jar']
|
19
19
|
else
|
20
|
-
s.platform
|
20
|
+
s.platform = Gem::Platform::RUBY
|
21
21
|
end
|
22
22
|
|
23
23
|
s.test_files = Dir['test/bson/*.rb']
|
24
24
|
s.executables = ['b2json', 'j2bson']
|
25
25
|
s.require_paths = ['lib']
|
26
26
|
s.has_rdoc = 'yard'
|
27
|
-
|
28
|
-
s.add_dependency('activesupport')
|
29
|
-
end
|
27
|
+
end
|
data/lib/bson.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
#
|
3
1
|
# --
|
4
2
|
# Copyright (C) 2008-2012 10gen Inc.
|
5
3
|
#
|
@@ -46,57 +44,75 @@ module BSON
|
|
46
44
|
bytebuf.rewind
|
47
45
|
return BSON.deserialize(bytebuf)
|
48
46
|
end
|
49
|
-
end
|
50
47
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
require File.join(jar_dir, 'jbson.jar')
|
55
|
-
require 'bson/bson_java'
|
56
|
-
module BSON
|
57
|
-
BSON_CODER = BSON_JAVA
|
48
|
+
def self.extension?
|
49
|
+
!((ENV.key?('BSON_EXT_DISABLED') && RUBY_PLATFORM =~ /java/) ||
|
50
|
+
(ENV.key?('BSON_EXT_DISABLED') || "\x01\x00\x00\x00".unpack("i")[0] != 1))
|
58
51
|
end
|
59
|
-
|
60
|
-
begin
|
61
|
-
# Need this for running test with and without c ext in Ruby 1.9.
|
62
|
-
raise LoadError if ENV['TEST_MODE'] && !ENV['C_EXT']
|
52
|
+
end
|
63
53
|
|
64
|
-
|
65
|
-
|
66
|
-
|
54
|
+
begin
|
55
|
+
# Skips loading extensions if one of the following is true:
|
56
|
+
# 1) JRuby and BSON_EXT_DISABLED is set.
|
57
|
+
# -OR-
|
58
|
+
# 2) Ruby MRI and big endian or BSON_EXT_DISABLED is set.
|
59
|
+
raise LoadError unless BSON.extension?
|
67
60
|
|
61
|
+
if RUBY_PLATFORM =~ /java/
|
62
|
+
require 'bson/bson_java'
|
63
|
+
module BSON
|
64
|
+
BSON_CODER = BSON_JAVA
|
65
|
+
end
|
66
|
+
else
|
68
67
|
require 'bson_ext/cbson'
|
69
68
|
raise LoadError unless defined?(CBson::VERSION)
|
70
69
|
require 'bson/bson_c'
|
71
70
|
module BSON
|
72
71
|
BSON_CODER = BSON_C
|
73
72
|
end
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
73
|
+
end
|
74
|
+
rescue LoadError
|
75
|
+
require 'bson/bson_ruby'
|
76
|
+
module BSON
|
77
|
+
BSON_CODER = BSON_RUBY
|
78
|
+
end
|
79
|
+
|
80
|
+
if RUBY_PLATFORM =~ /java/
|
81
|
+
unless ENV['TEST_MODE']
|
82
|
+
warn <<-NOTICE
|
83
|
+
** Notice: The BSON extension was not loaded. **
|
84
|
+
|
85
|
+
For optimal performance, use of the BSON extension is recommended. To
|
86
|
+
enable the extension make sure ENV['BSON_EXT_DISABLED'] is not set.
|
87
|
+
NOTICE
|
78
88
|
end
|
89
|
+
else
|
79
90
|
unless ENV['TEST_MODE']
|
80
|
-
warn
|
81
|
-
|
82
|
-
|
83
|
-
|
91
|
+
warn <<-NOTICE
|
92
|
+
** Notice: The native BSON extension was not loaded. **
|
93
|
+
|
94
|
+
For optimal performance, use of the BSON extension is recommended.
|
95
|
+
|
96
|
+
To enable the extension make sure ENV['BSON_EXT_DISABLED'] is not set
|
97
|
+
and run the following command:
|
98
|
+
|
99
|
+
gem install bson_ext
|
100
|
+
|
101
|
+
If you continue to receive this message after installing, make sure that
|
102
|
+
the bson_ext gem is in your load path.
|
103
|
+
NOTICE
|
84
104
|
end
|
85
105
|
end
|
86
106
|
end
|
87
107
|
|
88
|
-
require '
|
89
|
-
require '
|
90
|
-
|
108
|
+
require 'base64'
|
109
|
+
require 'bson/bson_ruby'
|
110
|
+
require 'bson/byte_buffer'
|
111
|
+
require 'bson/exceptions'
|
112
|
+
require 'bson/ordered_hash'
|
91
113
|
require 'bson/types/binary'
|
92
114
|
require 'bson/types/code'
|
93
115
|
require 'bson/types/dbref'
|
94
|
-
require 'bson/types/object_id'
|
95
116
|
require 'bson/types/min_max_keys'
|
117
|
+
require 'bson/types/object_id'
|
96
118
|
require 'bson/types/timestamp'
|
97
|
-
|
98
|
-
require 'base64'
|
99
|
-
require 'bson/ordered_hash'
|
100
|
-
require 'bson/byte_buffer'
|
101
|
-
require 'bson/bson_ruby'
|
102
|
-
require 'bson/exceptions'
|
data/lib/bson/bson_java.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
require 'jruby'
|
2
2
|
|
3
3
|
include Java
|
4
|
+
|
5
|
+
jar_dir = File.join(File.dirname(__FILE__), '../../ext/jbson')
|
6
|
+
require File.join(jar_dir, 'lib/java-bson.jar')
|
7
|
+
require File.join(jar_dir, 'target/jbson.jar')
|
8
|
+
|
4
9
|
module BSON
|
5
10
|
class BSON_JAVA
|
6
|
-
|
7
|
-
# TODO: Pool or cache instances of RubyBSONEncoder so that
|
8
|
-
# we don't create a new one on each call to #serialize.
|
9
11
|
def self.serialize(obj, check_keys=false, move_id=false, max_bson_size=BSON::DEFAULT_MAX_BSON_SIZE)
|
10
12
|
raise InvalidDocument, "BSON_JAVA.serialize takes a Hash" unless obj.is_a?(Hash)
|
11
13
|
enc = Java::OrgJbson::RubyBSONEncoder.new(JRuby.runtime, check_keys, move_id, max_bson_size)
|
data/lib/bson/bson_ruby.rb
CHANGED
@@ -17,6 +17,8 @@
|
|
17
17
|
# ++
|
18
18
|
|
19
19
|
module BSON
|
20
|
+
NULL_BYTE = "\x00"
|
21
|
+
|
20
22
|
# A BSON seralizer/deserializer in pure Ruby.
|
21
23
|
class BSON_RUBY
|
22
24
|
|
@@ -24,27 +26,32 @@ module BSON
|
|
24
26
|
|
25
27
|
@@max_bson_size = DEFAULT_MAX_BSON_SIZE
|
26
28
|
|
27
|
-
MINKEY
|
28
|
-
EOO
|
29
|
-
NUMBER
|
30
|
-
STRING
|
31
|
-
OBJECT
|
32
|
-
ARRAY
|
33
|
-
BINARY
|
34
|
-
UNDEFINED
|
35
|
-
OID
|
36
|
-
BOOLEAN
|
37
|
-
DATE
|
38
|
-
NULL
|
39
|
-
REGEX
|
40
|
-
REF
|
41
|
-
CODE
|
42
|
-
SYMBOL
|
29
|
+
MINKEY = -1
|
30
|
+
EOO = 0
|
31
|
+
NUMBER = 1
|
32
|
+
STRING = 2
|
33
|
+
OBJECT = 3
|
34
|
+
ARRAY = 4
|
35
|
+
BINARY = 5
|
36
|
+
UNDEFINED = 6
|
37
|
+
OID = 7
|
38
|
+
BOOLEAN = 8
|
39
|
+
DATE = 9
|
40
|
+
NULL = 10
|
41
|
+
REGEX = 11
|
42
|
+
REF = 12
|
43
|
+
CODE = 13
|
44
|
+
SYMBOL = 14
|
43
45
|
CODE_W_SCOPE = 15
|
44
|
-
NUMBER_INT
|
45
|
-
TIMESTAMP
|
46
|
-
NUMBER_LONG
|
47
|
-
MAXKEY
|
46
|
+
NUMBER_INT = 16
|
47
|
+
TIMESTAMP = 17
|
48
|
+
NUMBER_LONG = 18
|
49
|
+
MAXKEY = 127
|
50
|
+
|
51
|
+
INT32_MIN = -(1 << 31) + 1
|
52
|
+
INT32_MAX = (1 << 31) - 1
|
53
|
+
INT64_MIN = -2**64 / 2
|
54
|
+
INT64_MAX = 2**64 / 2 - 1
|
48
55
|
|
49
56
|
def initialize(max_bson_size=BSON::DEFAULT_MAX_BSON_SIZE)
|
50
57
|
@buf = ByteBuffer.new('', max_bson_size)
|
@@ -52,7 +59,6 @@ module BSON
|
|
52
59
|
end
|
53
60
|
|
54
61
|
if RUBY_VERSION >= '1.9'
|
55
|
-
NULL_BYTE = "\0".force_encoding('binary').freeze
|
56
62
|
UTF8_ENCODING = Encoding.find('utf-8')
|
57
63
|
BINARY_ENCODING = Encoding.find('binary')
|
58
64
|
|
@@ -65,8 +71,6 @@ module BSON
|
|
65
71
|
str.dup.force_encoding(BINARY_ENCODING)
|
66
72
|
end
|
67
73
|
else
|
68
|
-
NULL_BYTE = "\0"
|
69
|
-
|
70
74
|
def self.to_utf8_binary(str)
|
71
75
|
begin
|
72
76
|
str.unpack("U*")
|
@@ -299,8 +303,7 @@ module BSON
|
|
299
303
|
end
|
300
304
|
|
301
305
|
def deserialize_date_data(buf)
|
302
|
-
|
303
|
-
milliseconds = unsigned >= 2 ** 64 / 2 ? unsigned - 2**64 : unsigned
|
306
|
+
milliseconds = buf.get_long
|
304
307
|
Time.at(milliseconds.to_f / 1000.0).utc # at() takes fractional seconds
|
305
308
|
end
|
306
309
|
|
@@ -313,13 +316,11 @@ module BSON
|
|
313
316
|
end
|
314
317
|
|
315
318
|
def deserialize_number_int_data(buf)
|
316
|
-
|
317
|
-
unsigned >= 2**32 / 2 ? unsigned - 2**32 : unsigned
|
319
|
+
buf.get_int
|
318
320
|
end
|
319
321
|
|
320
322
|
def deserialize_number_long_data(buf)
|
321
|
-
|
322
|
-
unsigned >= 2 ** 64 / 2 ? unsigned - 2**64 : unsigned
|
323
|
+
buf.get_long
|
323
324
|
end
|
324
325
|
|
325
326
|
def deserialize_object_data(buf)
|
@@ -463,10 +464,10 @@ module BSON
|
|
463
464
|
self.class.serialize_key(buf, key)
|
464
465
|
buf.put_double(val)
|
465
466
|
else
|
466
|
-
if val >
|
467
|
+
if val > INT64_MAX or val < INT64_MIN
|
467
468
|
raise RangeError.new("MongoDB can only handle 8-byte ints")
|
468
469
|
end
|
469
|
-
if val >
|
470
|
+
if val > INT32_MAX or val < INT32_MIN
|
470
471
|
buf.put(NUMBER_LONG)
|
471
472
|
self.class.serialize_key(buf, key)
|
472
473
|
buf.put_long(val)
|
data/lib/bson/byte_buffer.rb
CHANGED
@@ -22,6 +22,10 @@ module BSON
|
|
22
22
|
|
23
23
|
attr_reader :order, :max_size
|
24
24
|
|
25
|
+
INT32_PACK = 'l<'.freeze
|
26
|
+
INT64_PACK = 'q<'.freeze
|
27
|
+
DOUBLE_PACK = 'E'.freeze
|
28
|
+
|
25
29
|
def initialize(initial_data="", max_size=BSON::DEFAULT_MAX_BSON_SIZE)
|
26
30
|
@str = case initial_data
|
27
31
|
when String then
|
@@ -37,45 +41,9 @@ module BSON
|
|
37
41
|
end
|
38
42
|
|
39
43
|
@cursor = @str.length
|
40
|
-
@order = :little_endian
|
41
|
-
@int_pack_order = 'V'
|
42
|
-
@double_pack_order = 'E'
|
43
44
|
@max_size = max_size
|
44
45
|
end
|
45
46
|
|
46
|
-
if RUBY_VERSION >= '1.9'
|
47
|
-
NULL_BYTE = "\0".force_encoding('binary').freeze
|
48
|
-
UTF8_ENCODING = Encoding.find('utf-8')
|
49
|
-
BINARY_ENCODING = Encoding.find('binary')
|
50
|
-
|
51
|
-
def self.to_utf8_binary(str)
|
52
|
-
str.encode(UTF8_ENCODING).force_encoding(BINARY_ENCODING)
|
53
|
-
end
|
54
|
-
else
|
55
|
-
NULL_BYTE = "\0"
|
56
|
-
|
57
|
-
def self.to_utf8_binary(str)
|
58
|
-
begin
|
59
|
-
str.unpack("U*")
|
60
|
-
rescue
|
61
|
-
raise InvalidStringEncoding, "String not valid utf-8: #{str.inspect}"
|
62
|
-
end
|
63
|
-
str
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def self.serialize_cstr(buf, val)
|
68
|
-
buf.append!(to_utf8_binary(val.to_s))
|
69
|
-
buf.append!(NULL_BYTE)
|
70
|
-
end
|
71
|
-
|
72
|
-
# +endianness+ should be :little_endian or :big_endian. Default is :little_endian
|
73
|
-
def order=(endianness)
|
74
|
-
@order = endianness
|
75
|
-
@int_pack_order = endianness == :little_endian ? 'V' : 'N'
|
76
|
-
@double_pack_order = endianness == :little_endian ? 'E' : 'G'
|
77
|
-
end
|
78
|
-
|
79
47
|
def rewind
|
80
48
|
@cursor = 0
|
81
49
|
end
|
@@ -147,31 +115,29 @@ module BSON
|
|
147
115
|
@cursor += array.length
|
148
116
|
end
|
149
117
|
|
150
|
-
def
|
118
|
+
def put_num(i, offset, bytes)
|
119
|
+
pack_type = bytes == 4 ? INT32_PACK : INT64_PACK
|
151
120
|
@cursor = offset if offset
|
152
121
|
if more?
|
153
|
-
@str[@cursor,
|
122
|
+
@str[@cursor, bytes] = [i].pack(pack_type)
|
154
123
|
else
|
155
124
|
ensure_length(@cursor)
|
156
|
-
@str << [i].pack(
|
125
|
+
@str << [i].pack(pack_type)
|
157
126
|
end
|
158
|
-
@cursor +=
|
127
|
+
@cursor += bytes
|
128
|
+
end
|
129
|
+
|
130
|
+
def put_int(i, offset=nil)
|
131
|
+
put_num(i, offset, 4)
|
159
132
|
end
|
160
133
|
|
161
134
|
def put_long(i, offset=nil)
|
162
|
-
offset
|
163
|
-
if @int_pack_order == 'N'
|
164
|
-
put_int(i >> 32, offset)
|
165
|
-
put_int(i & 0xffffffff, offset + 4)
|
166
|
-
else
|
167
|
-
put_int(i & 0xffffffff, offset)
|
168
|
-
put_int(i >> 32, offset + 4)
|
169
|
-
end
|
135
|
+
put_num(i, offset, 8)
|
170
136
|
end
|
171
137
|
|
172
138
|
def put_double(d, offset=nil)
|
173
139
|
a = []
|
174
|
-
[d].pack(
|
140
|
+
[d].pack(DOUBLE_PACK).each_byte { |b| a << b }
|
175
141
|
put_array(a, offset)
|
176
142
|
end
|
177
143
|
|
@@ -209,24 +175,21 @@ module BSON
|
|
209
175
|
check_read_length(4)
|
210
176
|
vals = @str[@cursor..@cursor+3]
|
211
177
|
@cursor += 4
|
212
|
-
vals.unpack(
|
178
|
+
vals.unpack(INT32_PACK)[0]
|
213
179
|
end
|
214
180
|
|
215
181
|
def get_long
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
else
|
221
|
-
(i2 << 32) + i1
|
222
|
-
end
|
182
|
+
check_read_length(8)
|
183
|
+
vals = @str[@cursor..@cursor+7]
|
184
|
+
@cursor += 8
|
185
|
+
vals.unpack(INT64_PACK)[0]
|
223
186
|
end
|
224
187
|
|
225
188
|
def get_double
|
226
189
|
check_read_length(8)
|
227
190
|
vals = @str[@cursor..@cursor+7]
|
228
191
|
@cursor += 8
|
229
|
-
vals.unpack(
|
192
|
+
vals.unpack(DOUBLE_PACK)[0]
|
230
193
|
end
|
231
194
|
|
232
195
|
def more?
|
@@ -0,0 +1,168 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# --
|
4
|
+
# Copyright (C) 2008-2012 10gen 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
|
+
|
19
|
+
require 'active_support'
|
20
|
+
begin
|
21
|
+
require 'active_support/hash_with_indifferent_access'
|
22
|
+
rescue LoadError
|
23
|
+
# For ActiveSupport 2
|
24
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
25
|
+
end
|
26
|
+
|
27
|
+
module ActiveSupport
|
28
|
+
class HashWithIndifferentAccess < Hash
|
29
|
+
def extractable_options?
|
30
|
+
true
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(constructor = {})
|
34
|
+
if constructor.is_a?(Hash)
|
35
|
+
super()
|
36
|
+
update(constructor)
|
37
|
+
else
|
38
|
+
super(constructor)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def default(key = nil)
|
43
|
+
if key.is_a?(Symbol) && include?(key = key.to_s)
|
44
|
+
self[key]
|
45
|
+
else
|
46
|
+
super
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.new_from_hash_copying_default(hash)
|
51
|
+
ActiveSupport::HashWithIndifferentAccess.new(hash).tap do |new_hash|
|
52
|
+
new_hash.default = hash.default
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
|
57
|
+
alias_method :regular_update, :update unless method_defined?(:regular_update)
|
58
|
+
|
59
|
+
# Assigns a new value to the hash:
|
60
|
+
#
|
61
|
+
# hash = HashWithIndifferentAccess.new
|
62
|
+
# hash[:key] = "value"
|
63
|
+
#
|
64
|
+
def []=(key, value)
|
65
|
+
regular_writer(convert_key(key), convert_value(value))
|
66
|
+
end
|
67
|
+
|
68
|
+
# Updates the instantized hash with values from the second:
|
69
|
+
#
|
70
|
+
# hash_1 = HashWithIndifferentAccess.new
|
71
|
+
# hash_1[:key] = "value"
|
72
|
+
#
|
73
|
+
# hash_2 = HashWithIndifferentAccess.new
|
74
|
+
# hash_2[:key] = "New Value!"
|
75
|
+
#
|
76
|
+
# hash_1.update(hash_2) # => {"key"=>"New Value!"}
|
77
|
+
#
|
78
|
+
def update(other_hash)
|
79
|
+
other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
|
80
|
+
self
|
81
|
+
end
|
82
|
+
|
83
|
+
alias_method :merge!, :update
|
84
|
+
|
85
|
+
# Checks the hash for a key matching the argument passed in:
|
86
|
+
#
|
87
|
+
# hash = HashWithIndifferentAccess.new
|
88
|
+
# hash["key"] = "value"
|
89
|
+
# hash.key? :key # => true
|
90
|
+
# hash.key? "key" # => true
|
91
|
+
#
|
92
|
+
def key?(key)
|
93
|
+
super(convert_key(key))
|
94
|
+
end
|
95
|
+
|
96
|
+
alias_method :include?, :key?
|
97
|
+
alias_method :has_key?, :key?
|
98
|
+
alias_method :member?, :key?
|
99
|
+
|
100
|
+
# Fetches the value for the specified key, same as doing hash[key]
|
101
|
+
def fetch(key, *extras)
|
102
|
+
super(convert_key(key), *extras)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns an array of the values at the specified indices:
|
106
|
+
#
|
107
|
+
# hash = HashWithIndifferentAccess.new
|
108
|
+
# hash[:a] = "x"
|
109
|
+
# hash[:b] = "y"
|
110
|
+
# hash.values_at("a", "b") # => ["x", "y"]
|
111
|
+
#
|
112
|
+
def values_at(*indices)
|
113
|
+
indices.collect {|key| self[convert_key(key)]}
|
114
|
+
end
|
115
|
+
|
116
|
+
# Returns an exact copy of the hash.
|
117
|
+
def dup
|
118
|
+
HashWithIndifferentAccess.new(self)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Merges the instantized and the specified hashes together, giving precedence to the values from the second hash
|
122
|
+
# Does not overwrite the existing hash.
|
123
|
+
def merge(hash)
|
124
|
+
self.dup.update(hash)
|
125
|
+
end
|
126
|
+
|
127
|
+
# Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
|
128
|
+
# This overloaded definition prevents returning a regular hash, if reverse_merge is called on a HashWithDifferentAccess.
|
129
|
+
def reverse_merge(other_hash)
|
130
|
+
super self.class.new_from_hash_copying_default(other_hash)
|
131
|
+
end
|
132
|
+
|
133
|
+
def reverse_merge!(other_hash)
|
134
|
+
replace(reverse_merge( other_hash ))
|
135
|
+
end
|
136
|
+
|
137
|
+
# Removes a specified key from the hash.
|
138
|
+
def delete(key)
|
139
|
+
super(convert_key(key))
|
140
|
+
end
|
141
|
+
|
142
|
+
def stringify_keys!; self end
|
143
|
+
def stringify_keys; dup end
|
144
|
+
def symbolize_keys; to_hash.symbolize_keys end
|
145
|
+
def to_options!; self end
|
146
|
+
|
147
|
+
# Convert to a Hash with String keys.
|
148
|
+
def to_hash
|
149
|
+
Hash.new(default).merge!(self)
|
150
|
+
end
|
151
|
+
|
152
|
+
protected
|
153
|
+
def convert_key(key)
|
154
|
+
key.kind_of?(Symbol) ? key.to_s : key
|
155
|
+
end
|
156
|
+
|
157
|
+
def convert_value(value)
|
158
|
+
case value
|
159
|
+
when Hash
|
160
|
+
self.class.new_from_hash_copying_default(value)
|
161
|
+
when Array
|
162
|
+
value.collect { |e| e.is_a?(Hash) ? self.class.new_from_hash_copying_default(e) : e }
|
163
|
+
else
|
164
|
+
value
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
data/lib/bson/types/binary.rb
CHANGED
@@ -26,10 +26,10 @@ module BSON
|
|
26
26
|
# Use this class when storing binary data in documents.
|
27
27
|
class Binary < ByteBuffer
|
28
28
|
|
29
|
-
SUBTYPE_SIMPLE
|
30
|
-
SUBTYPE_BYTES
|
31
|
-
SUBTYPE_UUID
|
32
|
-
SUBTYPE_MD5
|
29
|
+
SUBTYPE_SIMPLE = 0x00
|
30
|
+
SUBTYPE_BYTES = 0x02
|
31
|
+
SUBTYPE_UUID = 0x03
|
32
|
+
SUBTYPE_MD5 = 0x05
|
33
33
|
SUBTYPE_USER_DEFINED = 0x80
|
34
34
|
|
35
35
|
# One of the SUBTYPE_* constants. Default is SUBTYPE_BYTES.
|
data/lib/bson/types/object_id.rb
CHANGED
data/test/bson/bson_test.rb
CHANGED
@@ -349,7 +349,7 @@ class BSONTest < Test::Unit::TestCase
|
|
349
349
|
doc2 = @encoder.deserialize(bson)
|
350
350
|
|
351
351
|
# Java doesn't deserialize to DBRefs
|
352
|
-
if RUBY_PLATFORM =~ /java/
|
352
|
+
if RUBY_PLATFORM =~ /java/ && BSON.extension?
|
353
353
|
assert_equal 'namespace', doc2['dbref']['$ns']
|
354
354
|
assert_equal oid, doc2['dbref']['$id']
|
355
355
|
else
|
@@ -45,10 +45,6 @@ class ByteBufferTest < Test::Unit::TestCase
|
|
45
45
|
assert_equal 4, @buf.length
|
46
46
|
end
|
47
47
|
|
48
|
-
def test_default_order
|
49
|
-
assert_equal :little_endian, @buf.order
|
50
|
-
end
|
51
|
-
|
52
48
|
def test_long_length
|
53
49
|
@buf.put_long 1027
|
54
50
|
assert_equal 8, @buf.length
|
@@ -66,29 +62,31 @@ class ByteBufferTest < Test::Unit::TestCase
|
|
66
62
|
assert_equal 41.2, @buf.get_double
|
67
63
|
end
|
68
64
|
|
69
|
-
if
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
def test_serialize_cstr_validates_data_as_utf8
|
78
|
-
assert_raises(Encoding::UndefinedConversionError) do
|
79
|
-
ByteBuffer.serialize_cstr(@buf, "hello \xFF")
|
65
|
+
if BSON_CODER == BSON::BSON_RUBY
|
66
|
+
if defined?(Encoding)
|
67
|
+
def test_serialize_cstr_throws_error_for_bad_utf8
|
68
|
+
bad = "hello \xC8".force_encoding("ISO-8859-7")
|
69
|
+
assert_raises(BSON::InvalidStringEncoding) do
|
70
|
+
BSON_CODER::serialize_cstr(@buf, bad)
|
71
|
+
end
|
80
72
|
end
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
73
|
+
|
74
|
+
def test_serialize_cstr_does_not_validate_data_as_utf8
|
75
|
+
assert_raises(BSON::InvalidStringEncoding) do
|
76
|
+
BSON_CODER::serialize_cstr(@buf, "hello \xFF")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
else
|
80
|
+
def test_serialize_cstr_forces_encoding_to_utf8
|
81
|
+
# Unicode snowman (\u2603)
|
82
|
+
BSON_CODER::serialize_cstr(@buf, "hello \342\230\203")
|
83
|
+
assert_equal "hello \342\230\203\0", @buf.to_s
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_serialize_cstr_validates_data_as_utf8
|
87
|
+
assert_raises(BSON::InvalidStringEncoding) do
|
88
|
+
BSON_CODER::serialize_cstr(@buf, "hello \xFF")
|
89
|
+
end
|
92
90
|
end
|
93
91
|
end
|
94
92
|
end
|
@@ -1,6 +1,16 @@
|
|
1
1
|
# encoding:utf-8
|
2
2
|
require 'test_helper'
|
3
|
-
|
3
|
+
|
4
|
+
# Note: HashWithIndifferentAccess is so commonly used
|
5
|
+
# that we always need to make sure that the driver works
|
6
|
+
# with it. However, the bson gem should never need to
|
7
|
+
# depend on it.
|
8
|
+
|
9
|
+
# As a result, ActiveSupport is no longer a gem dependency and it should remain
|
10
|
+
# that way. It must be required by the application code or
|
11
|
+
# via bundler for developmet.
|
12
|
+
|
13
|
+
require 'bson/support/hash_with_indifferent_access'
|
4
14
|
|
5
15
|
class HashWithIndifferentAccessTest < Test::Unit::TestCase
|
6
16
|
include BSON
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bson
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.8.
|
4
|
+
version: 1.8.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,24 +12,8 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date:
|
16
|
-
dependencies:
|
17
|
-
- !ruby/object:Gem::Dependency
|
18
|
-
name: activesupport
|
19
|
-
requirement: !ruby/object:Gem::Requirement
|
20
|
-
none: false
|
21
|
-
requirements:
|
22
|
-
- - ! '>='
|
23
|
-
- !ruby/object:Gem::Version
|
24
|
-
version: '0'
|
25
|
-
type: :runtime
|
26
|
-
prerelease: false
|
27
|
-
version_requirements: !ruby/object:Gem::Requirement
|
28
|
-
none: false
|
29
|
-
requirements:
|
30
|
-
- - ! '>='
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: '0'
|
15
|
+
date: 2013-01-17 00:00:00.000000000 Z
|
16
|
+
dependencies: []
|
33
17
|
description: A Ruby BSON implementation for MongoDB. For more information about Mongo,
|
34
18
|
see http://www.mongodb.org. For more information on BSON, see http://www.bsonspec.org.
|
35
19
|
email: mongodb-dev@googlegroups.com
|
@@ -45,26 +29,27 @@ files:
|
|
45
29
|
- bin/b2json
|
46
30
|
- bin/j2bson
|
47
31
|
- lib/bson.rb
|
48
|
-
- lib/bson/ordered_hash.rb
|
49
32
|
- lib/bson/bson_c.rb
|
50
|
-
- lib/bson/types/dbref.rb
|
51
|
-
- lib/bson/types/min_max_keys.rb
|
52
|
-
- lib/bson/types/timestamp.rb
|
53
|
-
- lib/bson/types/code.rb
|
54
|
-
- lib/bson/types/binary.rb
|
55
|
-
- lib/bson/types/object_id.rb
|
56
33
|
- lib/bson/bson_java.rb
|
34
|
+
- lib/bson/bson_ruby.rb
|
57
35
|
- lib/bson/byte_buffer.rb
|
58
36
|
- lib/bson/exceptions.rb
|
59
|
-
- lib/bson/
|
60
|
-
-
|
61
|
-
-
|
37
|
+
- lib/bson/ordered_hash.rb
|
38
|
+
- lib/bson/support/hash_with_indifferent_access.rb
|
39
|
+
- lib/bson/types/binary.rb
|
40
|
+
- lib/bson/types/code.rb
|
41
|
+
- lib/bson/types/dbref.rb
|
42
|
+
- lib/bson/types/min_max_keys.rb
|
43
|
+
- lib/bson/types/object_id.rb
|
44
|
+
- lib/bson/types/timestamp.rb
|
62
45
|
- test/bson/binary_test.rb
|
63
|
-
- test/bson/
|
64
|
-
- test/bson/timestamp_test.rb
|
46
|
+
- test/bson/bson_test.rb
|
65
47
|
- test/bson/byte_buffer_test.rb
|
66
|
-
- test/bson/
|
48
|
+
- test/bson/hash_with_indifferent_access_test.rb
|
67
49
|
- test/bson/json_test.rb
|
50
|
+
- test/bson/object_id_test.rb
|
51
|
+
- test/bson/ordered_hash_test.rb
|
52
|
+
- test/bson/timestamp_test.rb
|
68
53
|
homepage: http://www.mongodb.org
|
69
54
|
licenses: []
|
70
55
|
post_install_message:
|
@@ -77,6 +62,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
77
62
|
- - ! '>='
|
78
63
|
- !ruby/object:Gem::Version
|
79
64
|
version: '0'
|
65
|
+
segments:
|
66
|
+
- 0
|
67
|
+
hash: 682470089809443431
|
80
68
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
69
|
none: false
|
82
70
|
requirements:
|
@@ -90,12 +78,12 @@ signing_key:
|
|
90
78
|
specification_version: 3
|
91
79
|
summary: Ruby implementation of BSON
|
92
80
|
test_files:
|
93
|
-
- test/bson/hash_with_indifferent_access_test.rb
|
94
|
-
- test/bson/bson_test.rb
|
95
81
|
- test/bson/binary_test.rb
|
96
|
-
- test/bson/
|
97
|
-
- test/bson/timestamp_test.rb
|
82
|
+
- test/bson/bson_test.rb
|
98
83
|
- test/bson/byte_buffer_test.rb
|
99
|
-
- test/bson/
|
84
|
+
- test/bson/hash_with_indifferent_access_test.rb
|
100
85
|
- test/bson/json_test.rb
|
86
|
+
- test/bson/object_id_test.rb
|
87
|
+
- test/bson/ordered_hash_test.rb
|
88
|
+
- test/bson/timestamp_test.rb
|
101
89
|
has_rdoc: yard
|