bson 1.3.1 → 1.4.0

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.

@@ -18,10 +18,10 @@
18
18
 
19
19
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
20
20
 
21
- MINIMUM_BSON_EXT_VERSION = "1.3.1"
21
+ MINIMUM_BSON_EXT_VERSION = "1.4.0"
22
22
 
23
23
  module BSON
24
- VERSION = "1.3.1"
24
+ VERSION = "1.4.0"
25
25
 
26
26
  if defined? Mongo::DEFAULT_MAX_BSON_SIZE
27
27
  DEFAULT_MAX_BSON_SIZE = Mongo::DEFAULT_MAX_BSON_SIZE
@@ -56,7 +56,7 @@ end
56
56
 
57
57
  if RUBY_PLATFORM =~ /java/
58
58
  jar_dir = File.join(File.dirname(__FILE__), '..', 'ext', 'java', 'jar')
59
- require File.join(jar_dir, 'mongo-2.4.jar')
59
+ require File.join(jar_dir, 'mongo-2.6.5.jar')
60
60
  require File.join(jar_dir, 'jbson.jar')
61
61
  require 'bson/bson_java'
62
62
  module BSON
@@ -20,8 +20,8 @@
20
20
  module BSON
21
21
  class BSON_C
22
22
 
23
- def self.serialize(obj, check_keys=false, move_id=false)
24
- ByteBuffer.new(CBson.serialize(obj, check_keys, move_id))
23
+ def self.serialize(obj, check_keys=false, move_id=false, max_bson_size=BSON::DEFAULT_MAX_BSON_SIZE)
24
+ ByteBuffer.new(CBson.serialize(obj, check_keys, move_id, max_bson_size))
25
25
  end
26
26
 
27
27
  def self.deserialize(buf=nil)
@@ -29,10 +29,12 @@ module BSON
29
29
  end
30
30
 
31
31
  def self.max_bson_size
32
+ warn "BSON::BSON_CODER.max_bson_size is deprecated and will be removed in v2.0."
32
33
  CBson.max_bson_size
33
34
  end
34
35
 
35
36
  def self.update_max_bson_size(connection)
37
+ warn "BSON::BSON_CODER.update_max_bson_size is deprecated and now a no-op. It will be removed in v2.0."
36
38
  CBson.update_max_bson_size(connection)
37
39
  end
38
40
  end
@@ -4,9 +4,9 @@ module BSON
4
4
 
5
5
  # TODO: Pool or cache instances of RubyBSONEncoder so that
6
6
  # we don't create a new one on each call to #serialize.
7
- def self.serialize(obj, check_keys=false, move_id=false)
7
+ def self.serialize(obj, check_keys=false, move_id=false, max_bson_size=BSON::DEFAULT_MAX_BSON_SIZE)
8
8
  raise InvalidDocument, "BSON_JAVA.serialize takes a Hash" unless obj.is_a?(Hash)
9
- enc = Java::OrgJbson::RubyBSONEncoder.new(JRuby.runtime, check_keys, move_id)
9
+ enc = Java::OrgJbson::RubyBSONEncoder.new(JRuby.runtime, check_keys, move_id, max_bson_size)
10
10
  ByteBuffer.new(enc.encode(obj))
11
11
  end
12
12
 
@@ -18,10 +18,12 @@ module BSON
18
18
  end
19
19
 
20
20
  def self.max_bson_size
21
+ warn "BSON::BSON_CODER.max_bson_size is deprecated and will be removed in v2.0."
21
22
  Java::OrgJbson::RubyBSONEncoder.max_bson_size(self)
22
23
  end
23
24
 
24
25
  def self.update_max_bson_size(connection)
26
+ warn "BSON::BSON_CODER.update_max_bson_size is deprecated and now a no-op. It will be removed in v2.0."
25
27
  Java::OrgJbson::RubyBSONEncoder.update_max_bson_size(self, connection)
26
28
  end
27
29
  end
@@ -46,8 +46,8 @@ module BSON
46
46
  NUMBER_LONG = 18
47
47
  MAXKEY = 127
48
48
 
49
- def initialize
50
- @buf = ByteBuffer.new
49
+ def initialize(max_bson_size=BSON::DEFAULT_MAX_BSON_SIZE)
50
+ @buf = ByteBuffer.new('', max_bson_size)
51
51
  @encoder = BSON_RUBY
52
52
  end
53
53
 
@@ -78,10 +78,12 @@ module BSON
78
78
  end
79
79
 
80
80
  def self.update_max_bson_size(connection)
81
+ warn "BSON::BSON_CODER.update_max_bson_size is deprecated and now a no-op. It will be removed in v2.0."
81
82
  @@max_bson_size = connection.max_bson_size
82
83
  end
83
84
 
84
85
  def self.max_bson_size
86
+ warn "BSON::BSON_CODER.max_bson_size is deprecated and will be removed in v2.0."
85
87
  @@max_bson_size
86
88
  end
87
89
 
@@ -105,8 +107,8 @@ module BSON
105
107
 
106
108
  # Serializes an object.
107
109
  # Implemented to ensure an API compatible with BSON extension.
108
- def self.serialize(obj, check_keys=false, move_id=false)
109
- new.serialize(obj, check_keys, move_id)
110
+ def self.serialize(obj, check_keys=false, move_id=false, max_bson_size=BSON::DEFAULT_MAX_BSON_SIZE)
111
+ new(max_bson_size).serialize(obj, check_keys, move_id)
110
112
  end
111
113
 
112
114
  def self.deserialize(buf=nil)
@@ -137,8 +139,9 @@ module BSON
137
139
  end
138
140
 
139
141
  serialize_eoo_element(@buf)
140
- if @buf.size > @@max_bson_size
141
- raise InvalidDocument, "Document is too large (#{@buf.size}). BSON documents are limited to #{@@max_bson_size} bytes."
142
+ if @buf.size > @buf.max_size
143
+ raise InvalidDocument, "Document is too large (#{@buf.size}). " +
144
+ "This BSON documents is limited to #{@buf.max_size} bytes."
142
145
  end
143
146
  @buf.put_int(@buf.size, 0)
144
147
  @buf
@@ -20,9 +20,9 @@
20
20
  module BSON
21
21
  class ByteBuffer
22
22
 
23
- attr_reader :order
23
+ attr_reader :order, :max_size
24
24
 
25
- def initialize(initial_data="")
25
+ def initialize(initial_data="", max_size=BSON::DEFAULT_MAX_BSON_SIZE)
26
26
  @str = case initial_data
27
27
  when String then
28
28
  if initial_data.respond_to?(:force_encoding)
@@ -40,6 +40,7 @@ module BSON
40
40
  @order = :little_endian
41
41
  @int_pack_order = 'V'
42
42
  @double_pack_order = 'E'
43
+ @max_size = max_size
43
44
  end
44
45
 
45
46
  if RUBY_VERSION >= '1.9'
@@ -67,11 +67,10 @@ module BSON
67
67
  end
68
68
 
69
69
  def keys
70
- @ordered_keys# || []
70
+ @ordered_keys.dup
71
71
  end
72
72
 
73
73
  def []=(key, value)
74
- #@ordered_keys ||= []
75
74
  unless has_key?(key)
76
75
  @ordered_keys << key
77
76
  end
@@ -79,14 +78,12 @@ module BSON
79
78
  end
80
79
 
81
80
  def each
82
- #@ordered_keys ||= []
83
81
  @ordered_keys.each { |k| yield k, self[k] }
84
82
  self
85
83
  end
86
84
  alias :each_pair :each
87
85
 
88
86
  def to_a
89
- #@ordered_keys ||= []
90
87
  @ordered_keys.map { |k| [k, self[k]] }
91
88
  end
92
89
 
@@ -94,6 +91,11 @@ module BSON
94
91
  collect { |k, v| v }
95
92
  end
96
93
 
94
+ def replace(other)
95
+ @ordered_keys.replace(other.keys)
96
+ super
97
+ end
98
+
97
99
  def merge(other)
98
100
  oh = self.dup
99
101
  oh.merge!(other)
@@ -101,17 +103,15 @@ module BSON
101
103
  end
102
104
 
103
105
  def merge!(other)
104
- #@ordered_keys ||= []
105
106
  @ordered_keys += other.keys # unordered if not an BSON::OrderedHash
106
107
  @ordered_keys.uniq!
107
108
  super(other)
108
109
  end
109
110
 
110
111
  alias :update :merge!
111
-
112
+
112
113
  def dup
113
114
  result = OrderedHash.new
114
- #@ordered_keys ||= []
115
115
  @ordered_keys.each do |key|
116
116
  result[key] = self[key]
117
117
  end
@@ -119,9 +119,9 @@ module BSON
119
119
  end
120
120
 
121
121
  def inspect
122
- str = '{'
122
+ str = "#<BSON::OrderedHash:0x#{self.object_id.to_s(16)} {"
123
123
  str << (@ordered_keys || []).collect { |k| "\"#{k}\"=>#{self.[](k).inspect}" }.join(", ")
124
- str << '}'
124
+ str << '}>'
125
125
  end
126
126
 
127
127
  def delete(key, &block)
@@ -159,20 +159,22 @@ module BSON
159
159
  @ordered_keys = []
160
160
  end
161
161
 
162
- def hash
163
- code = 17
164
- each_pair do |key, value|
165
- code = 37 * code + key.hash
166
- code = 37 * code + value.hash
162
+ if RUBY_VERSION =~ /1.8.6/
163
+ def hash
164
+ code = 17
165
+ each_pair do |key, value|
166
+ code = 37 * code + key.hash
167
+ code = 37 * code + value.hash
168
+ end
169
+ code & 0x7fffffff
167
170
  end
168
- code & 0x7fffffff
169
- end
170
171
 
171
- def eql?(o)
172
- if o.instance_of? BSON::OrderedHash
173
- self.hash == o.hash
174
- else
175
- false
172
+ def eql?(o)
173
+ if o.instance_of? BSON::OrderedHash
174
+ self.hash == o.hash
175
+ else
176
+ false
177
+ end
176
178
  end
177
179
  end
178
180
 
@@ -30,9 +30,6 @@ module BSON
30
30
  #
31
31
  # @core objectids
32
32
  class ObjectId
33
- @@lock = Mutex.new
34
- @@index = 0
35
-
36
33
  attr_accessor :data
37
34
 
38
35
  # Create a new object id. If no parameter is given, an id corresponding
@@ -71,7 +68,7 @@ module BSON
71
68
  # succeeding the timestamp will be zeroed; if true, they'll
72
69
  # consist of the standard machine id, pid, and counter.
73
70
  #
74
- # @return [Mongo::ObjectId]
71
+ # @return [BSON::ObjectId]
75
72
  #
76
73
  # @example Return all document created before Jan 1, 2010.
77
74
  # time = Time.utc(2010, 1, 1)
@@ -90,7 +87,7 @@ module BSON
90
87
  #
91
88
  # @param [Hash] doc a document requiring an _id.
92
89
  #
93
- # @return [Mongo::ObjectId, Object] returns a newly-created or
90
+ # @return [BSON::ObjectId, Object] returns a newly-created or
94
91
  # current _id for the given document.
95
92
  def self.create_pk(doc)
96
93
  doc.has_key?(:_id) || doc.has_key?('_id') ? doc : doc.merge!(:_id => self.new)
@@ -124,9 +121,9 @@ module BSON
124
121
  #
125
122
  # @param [String] str
126
123
  #
127
- # @return [Mongo::ObjectId]
124
+ # @return [BSON::ObjectId]
128
125
  def self.from_string(str)
129
- raise InvalidObjectId, "illegal ObjectId format" unless legal?(str)
126
+ raise InvalidObjectId, "illegal ObjectId format: #{str}" unless legal?(str)
130
127
  data = []
131
128
  12.times do |i|
132
129
  data[i] = str[i * 2, 2].to_i(16)
@@ -170,35 +167,59 @@ module BSON
170
167
  Time.at(@data.pack("C4").unpack("N")[0]).utc
171
168
  end
172
169
 
170
+ def self.machine_id
171
+ @@machine_id
172
+ end
173
+
173
174
  private
174
175
 
175
- # This gets overwritten by the C extension if it loads.
176
- def generate(oid_time=nil)
177
- oid = ''
176
+ if RUBY_PLATFORM =~ /java/
177
+ @@generator = Java::OrgBsonTypes::ObjectId
178
+ @@machine_id = [@@generator.genMachineId].pack("N")[0,3]
178
179
 
179
- # 4 bytes current time
180
- if oid_time
181
- t = oid_time.to_i
182
- else
183
- t = Time.new.to_i
180
+ def generate(oid_time=nil)
181
+ data = (oid_time ? @@generator.new(oid_time) : @@generator.new)
182
+
183
+ oid = ''
184
+ oid += [data.timeSecond].pack("N")
185
+ oid += [data._machine].pack("N")
186
+ oid += [data._inc].pack("N")
187
+ oid.unpack("C12")
184
188
  end
185
- oid += [t].pack("N")
186
189
 
187
- # 3 bytes machine
188
- oid += Digest::MD5.digest(Socket.gethostname)[0, 3]
190
+ else
191
+ @@lock = Mutex.new
192
+ @@index = 0
193
+ @@machine_id = Digest::MD5.digest(Socket.gethostname)[0, 3]
189
194
 
190
- # 2 bytes pid
191
- oid += [Process.pid % 0xFFFF].pack("n")
195
+ # This gets overwritten by the C extension if it loads.
196
+ def generate(oid_time=nil)
197
+ oid = ''
192
198
 
193
- # 3 bytes inc
194
- oid += [get_inc].pack("N")[1, 3]
199
+ # 4 bytes current time
200
+ if oid_time
201
+ t = oid_time.to_i
202
+ else
203
+ t = Time.new.to_i
204
+ end
205
+ oid += [t].pack("N")
195
206
 
196
- oid.unpack("C12")
197
- end
207
+ # 3 bytes machine
208
+ oid += @@machine_id
209
+
210
+ # 2 bytes pid
211
+ oid += [Process.pid % 0xFFFF].pack("n")
212
+
213
+ # 3 bytes inc
214
+ oid += [get_inc].pack("N")[1, 3]
215
+
216
+ oid.unpack("C12")
217
+ end
198
218
 
199
- def get_inc
200
- @@lock.synchronize do
201
- @@index = (@@index + 1) % 0xFFFFFF
219
+ def get_inc
220
+ @@lock.synchronize do
221
+ @@index = (@@index + 1) % 0xFFFFFF
222
+ end
202
223
  end
203
224
  end
204
225
  end
@@ -1,5 +1,5 @@
1
1
  # encoding:utf-8
2
- require './test/test_helper'
2
+ require './test/bson/test_helper'
3
3
 
4
4
  class BinaryTest < Test::Unit::TestCase
5
5
  context "Inspecting" do
@@ -0,0 +1,30 @@
1
+ # encoding:utf-8
2
+ require './test/bson/test_helper'
3
+ require 'complex'
4
+ require 'bigdecimal'
5
+ require 'rational'
6
+
7
+ class BSONTest < Test::Unit::TestCase
8
+
9
+ include BSON
10
+
11
+ def setup
12
+ @encoder = BSON::BSON_CODER
13
+ end
14
+
15
+ def assert_doc_pass(doc, options={})
16
+ bson = @encoder.serialize(doc)
17
+ if options[:debug]
18
+ puts "DEBUGGING DOC:"
19
+ p bson.to_a
20
+ puts "DESERIALIZES TO:"
21
+ end
22
+ assert_equal @encoder.serialize(doc).to_a, bson.to_a
23
+ assert_equal doc, @encoder.deserialize(bson)
24
+ end
25
+
26
+ def test_string
27
+ assert_doc_pass({:a => "hello"})
28
+ end
29
+
30
+ end
@@ -1,5 +1,6 @@
1
1
  # encoding:utf-8
2
- require './test/test_helper'
2
+ require './test/bson/test_helper'
3
+ require 'set'
3
4
 
4
5
  if RUBY_VERSION < '1.9'
5
6
  require 'complex'
@@ -436,8 +437,10 @@ class BSONTest < Test::Unit::TestCase
436
437
  0x00, 0x00, 0x14, 0x00,
437
438
  0x00, 0x00, 0x00])
438
439
 
439
- assert_equal 4, result["test"][0]
440
- assert_equal 20, result["test"][1]
440
+ silently do
441
+ assert_equal 4, result["test"][0]
442
+ assert_equal 20, result["test"][1]
443
+ end
441
444
  end
442
445
  end
443
446
 
@@ -1,5 +1,5 @@
1
1
  # encoding: binary
2
- require './test/test_helper'
2
+ require './test/bson/test_helper'
3
3
 
4
4
  class ByteBufferTest < Test::Unit::TestCase
5
5
  include BSON
@@ -1,5 +1,5 @@
1
1
  # encoding:utf-8
2
- require './test/test_helper'
2
+ require './test/bson/test_helper'
3
3
  require './test/support/hash_with_indifferent_access'
4
4
 
5
5
  class HashWithIndifferentAccessTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require './test/test_helper'
1
+ require './test/bson/test_helper'
2
2
  require 'rubygems'
3
3
  require 'json'
4
4
 
@@ -1,12 +1,9 @@
1
- require './test/test_helper'
1
+ require './test/bson/test_helper'
2
2
  require 'rubygems'
3
3
  require 'json'
4
4
 
5
5
  class ObjectIdTest < Test::Unit::TestCase
6
6
 
7
- include Mongo
8
- include BSON
9
-
10
7
  def setup
11
8
  @o = ObjectId.new
12
9
  end
@@ -65,18 +62,6 @@ class ObjectIdTest < Test::Unit::TestCase
65
62
  assert_equal "BSON::ObjectId('#{@o.to_s}')", @o.inspect
66
63
  end
67
64
 
68
- def test_save_and_restore
69
- db = standard_connection.db(MONGO_TEST_DB)
70
- coll = db.collection('test')
71
-
72
- coll.remove
73
- coll << {'a' => 1, '_id' => @o}
74
-
75
- row = coll.find().collect.first
76
- assert_equal 1, row['a']
77
- assert_equal @o, row['_id']
78
- end
79
-
80
65
  def test_from_string
81
66
  hex_str = @o.to_s
82
67
  o2 = ObjectId.from_string(hex_str)
@@ -134,8 +119,7 @@ class ObjectIdTest < Test::Unit::TestCase
134
119
  time = Time.now.utc
135
120
  id = ObjectId.from_time(time, :unique => true)
136
121
 
137
- mac_id = Digest::MD5.digest(Socket.gethostname)[0, 3].unpack("C3")
138
- assert_equal id.to_a[4, 3], mac_id
122
+ assert_equal id.to_a[4, 3], ObjectId.machine_id.unpack("C3")
139
123
  assert_equal time.to_i, id.generation_time.to_i
140
124
 
141
125
  id2 = ObjectId.new(nil, time)
@@ -1,4 +1,4 @@
1
- require './test/test_helper'
1
+ require './test/bson/test_helper'
2
2
 
3
3
  class OrderedHashTest < Test::Unit::TestCase
4
4
 
@@ -38,6 +38,7 @@ class OrderedHashTest < Test::Unit::TestCase
38
38
  same_doc = BSON::OrderedHash.new
39
39
  same_doc['_id'] = 'ab12'
40
40
  same_doc['name'] = 'test'
41
+
41
42
  list << doc
42
43
  list << same_doc
43
44
 
@@ -45,6 +46,23 @@ class OrderedHashTest < Test::Unit::TestCase
45
46
  assert_equal 1, list.uniq.size
46
47
  end
47
48
 
49
+ if !(RUBY_VERSION =~ /1.8.6/)
50
+ def test_compatibility_with_hash
51
+ list = []
52
+ doc = BSON::OrderedHash.new
53
+ doc['_id'] = 'ab12'
54
+ doc['name'] = 'test'
55
+
56
+ doc2 = {}
57
+ doc2['_id'] = 'ab12'
58
+ doc2['name'] = 'test'
59
+ list << doc
60
+ list << doc2
61
+
62
+ assert_equal 1, list.uniq.size
63
+ end
64
+ end
65
+
48
66
  def test_equality
49
67
  a = BSON::OrderedHash.new
50
68
  a['x'] = 1
@@ -76,6 +94,21 @@ class OrderedHashTest < Test::Unit::TestCase
76
94
  assert_equal @ordered_keys, @oh.keys
77
95
  end
78
96
 
97
+ def test_replace
98
+ h1 = BSON::OrderedHash.new
99
+ h1[:a] = 1
100
+ h1[:b] = 2
101
+
102
+ h2 = BSON::OrderedHash.new
103
+ h2[:c] = 3
104
+ h2[:d] = 4
105
+ h1.replace(h2)
106
+
107
+ assert_equal [:c, :d], h1.keys
108
+ assert_equal [3, 4], h1.values
109
+ assert h1.keys.object_id != h2.keys.object_id
110
+ end
111
+
79
112
  def test_to_a_order_preserved
80
113
  assert_equal @ordered_keys, @oh.to_a.map {|m| m.first}
81
114
  end
@@ -158,8 +191,10 @@ class OrderedHashTest < Test::Unit::TestCase
158
191
  assert_equal [1, 2, 3, 'foo'], noob.values
159
192
  end
160
193
 
161
- def test_inspect_retains_order
162
- assert_equal '{"c"=>1, "a"=>2, "z"=>3}', @oh.inspect
194
+ if RUBY_VERSION < "1.9.2"
195
+ def test_inspect_retains_order
196
+ assert_equal "#<BSON::OrderedHash:0x#{@oh.object_id.to_s(16)} {\"c\"=>1, \"a\"=>2, \"z\"=>3}>", @oh.inspect
197
+ end
163
198
  end
164
199
 
165
200
  def test_clear
@@ -0,0 +1,46 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'bson')
2
+ require 'rubygems' if RUBY_VERSION < '1.9.0' && ENV['C_EXT']
3
+ require 'test/unit'
4
+
5
+ def silently
6
+ warn_level = $VERBOSE
7
+ $VERBOSE = nil
8
+ result = yield
9
+ $VERBOSE = warn_level
10
+ result
11
+ end
12
+
13
+ begin
14
+ require 'rubygems' if RUBY_VERSION < "1.9.0" && !ENV['C_EXT']
15
+ silently { require 'shoulda' }
16
+ silently { require 'mocha' }
17
+ rescue LoadError
18
+ puts <<MSG
19
+
20
+ This test suite requires shoulda and mocha.
21
+ You can install them as follows:
22
+ gem install shoulda
23
+ gem install mocha
24
+
25
+ MSG
26
+
27
+ exit
28
+ end
29
+
30
+ require 'bson_ext/cbson' if !(RUBY_PLATFORM =~ /java/) && ENV['C_EXT']
31
+
32
+ class Test::Unit::TestCase
33
+ include BSON
34
+
35
+ def assert_raise_error(klass, message)
36
+ begin
37
+ yield
38
+ rescue => e
39
+ assert_equal klass, e.class
40
+ assert e.message.include?(message), "#{e.message} does not include #{message}."
41
+ else
42
+ flunk "Expected assertion #{klass} but none was raised."
43
+ end
44
+ end
45
+
46
+ end
@@ -1,7 +1,6 @@
1
- require './test/test_helper'
1
+ require './test/bson/test_helper'
2
2
 
3
- class TiumestampTest < Test::Unit::TestCase
4
- include Mongo
3
+ class TimestampTest < Test::Unit::TestCase
5
4
 
6
5
  def test_timestamp_equality
7
6
  t1 = Timestamp.new(5000, 200)
@@ -9,16 +8,39 @@ class TiumestampTest < Test::Unit::TestCase
9
8
  assert_equal t2, t1
10
9
  end
11
10
 
11
+ def test_timestamp_range
12
+ t = 1;
13
+ while(t < 1_000_000_000 ) do
14
+ ts = Timestamp.new(t, 0)
15
+ doc = {:ts => ts}
16
+ bson = BSON::BSON_CODER.serialize(doc)
17
+ assert_equal doc[:ts], BSON::BSON_CODER.deserialize(bson)['ts']
18
+ t = t * 10
19
+ end
20
+ end
21
+
22
+ def test_timestamp_32bit_compatibility
23
+ max_32bit_fixnum = (1 << 30) - 1
24
+ test_val = max_32bit_fixnum + 10
25
+
26
+ ts = Timestamp.new(test_val, test_val)
27
+ doc = {:ts => ts}
28
+ bson = BSON::BSON_CODER.serialize(doc)
29
+ assert_equal doc[:ts], BSON::BSON_CODER.deserialize(bson)['ts']
30
+ end
31
+
12
32
  def test_implements_array_for_backward_compatibility
13
- ts = Timestamp.new(5000, 200)
14
- assert_equal 200, ts[0]
15
- assert_equal 5000, ts[1]
33
+ silently do
34
+ ts = Timestamp.new(5000, 200)
35
+ assert_equal 200, ts[0]
36
+ assert_equal 5000, ts[1]
16
37
 
17
- array = ts.map {|t| t }
18
- assert_equal 2, array.length
38
+ array = ts.map {|t| t }
39
+ assert_equal 2, array.length
19
40
 
20
- assert_equal 200, array[0]
21
- assert_equal 5000, array[1]
41
+ assert_equal 200, array[0]
42
+ assert_equal 5000, array[1]
43
+ end
22
44
  end
23
45
 
24
46
  end
@@ -0,0 +1,186 @@
1
+ # Note: HashWithIndifferentAccess is so commonly used
2
+ # that we always need to make sure that the driver works
3
+ # with it.
4
+ #require File.join(File.dirname(__FILE__), 'keys.rb')
5
+
6
+ # This class has dubious semantics and we only have it so that
7
+ # people can write params[:key] instead of params['key']
8
+ # and they get the same value for both keys.
9
+
10
+ class Hash
11
+ # Return a new hash with all keys converted to strings.
12
+ def stringify_keys
13
+ dup.stringify_keys!
14
+ end
15
+
16
+ # Destructively convert all keys to strings.
17
+ def stringify_keys!
18
+ keys.each do |key|
19
+ self[key.to_s] = delete(key)
20
+ end
21
+ self
22
+ end
23
+
24
+ # Return a new hash with all keys converted to symbols, as long as
25
+ # they respond to +to_sym+.
26
+ def symbolize_keys
27
+ dup.symbolize_keys!
28
+ end
29
+
30
+ # Destructively convert all keys to symbols, as long as they respond
31
+ # to +to_sym+.
32
+ def symbolize_keys!
33
+ keys.each do |key|
34
+ self[(key.to_sym rescue key) || key] = delete(key)
35
+ end
36
+ self
37
+ end
38
+
39
+ alias_method :to_options, :symbolize_keys
40
+ #alias_method :to_options!, :symbolize_keys!
41
+ end
42
+
43
+ module ActiveSupport
44
+ class HashWithIndifferentAccess < Hash
45
+ def extractable_options?
46
+ true
47
+ end
48
+
49
+ def initialize(constructor = {})
50
+ if constructor.is_a?(Hash)
51
+ super()
52
+ update(constructor)
53
+ else
54
+ super(constructor)
55
+ end
56
+ end
57
+
58
+ def default(key = nil)
59
+ if key.is_a?(Symbol) && include?(key = key.to_s)
60
+ self[key]
61
+ else
62
+ super
63
+ end
64
+ end
65
+
66
+ def self.new_from_hash_copying_default(hash)
67
+ ActiveSupport::HashWithIndifferentAccess.new(hash).tap do |new_hash|
68
+ new_hash.default = hash.default
69
+ end
70
+ end
71
+
72
+ alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
73
+ alias_method :regular_update, :update unless method_defined?(:regular_update)
74
+
75
+ # Assigns a new value to the hash:
76
+ #
77
+ # hash = HashWithIndifferentAccess.new
78
+ # hash[:key] = "value"
79
+ #
80
+ def []=(key, value)
81
+ regular_writer(convert_key(key), convert_value(value))
82
+ end
83
+
84
+ # Updates the instantized hash with values from the second:
85
+ #
86
+ # hash_1 = HashWithIndifferentAccess.new
87
+ # hash_1[:key] = "value"
88
+ #
89
+ # hash_2 = HashWithIndifferentAccess.new
90
+ # hash_2[:key] = "New Value!"
91
+ #
92
+ # hash_1.update(hash_2) # => {"key"=>"New Value!"}
93
+ #
94
+ def update(other_hash)
95
+ other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
96
+ self
97
+ end
98
+
99
+ alias_method :merge!, :update
100
+
101
+ # Checks the hash for a key matching the argument passed in:
102
+ #
103
+ # hash = HashWithIndifferentAccess.new
104
+ # hash["key"] = "value"
105
+ # hash.key? :key # => true
106
+ # hash.key? "key" # => true
107
+ #
108
+ def key?(key)
109
+ super(convert_key(key))
110
+ end
111
+
112
+ alias_method :include?, :key?
113
+ alias_method :has_key?, :key?
114
+ alias_method :member?, :key?
115
+
116
+ # Fetches the value for the specified key, same as doing hash[key]
117
+ def fetch(key, *extras)
118
+ super(convert_key(key), *extras)
119
+ end
120
+
121
+ # Returns an array of the values at the specified indices:
122
+ #
123
+ # hash = HashWithIndifferentAccess.new
124
+ # hash[:a] = "x"
125
+ # hash[:b] = "y"
126
+ # hash.values_at("a", "b") # => ["x", "y"]
127
+ #
128
+ def values_at(*indices)
129
+ indices.collect {|key| self[convert_key(key)]}
130
+ end
131
+
132
+ # Returns an exact copy of the hash.
133
+ def dup
134
+ HashWithIndifferentAccess.new(self)
135
+ end
136
+
137
+ # Merges the instantized and the specified hashes together, giving precedence to the values from the second hash
138
+ # Does not overwrite the existing hash.
139
+ def merge(hash)
140
+ self.dup.update(hash)
141
+ end
142
+
143
+ # Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
144
+ # This overloaded definition prevents returning a regular hash, if reverse_merge is called on a HashWithDifferentAccess.
145
+ def reverse_merge(other_hash)
146
+ super self.class.new_from_hash_copying_default(other_hash)
147
+ end
148
+
149
+ def reverse_merge!(other_hash)
150
+ replace(reverse_merge( other_hash ))
151
+ end
152
+
153
+ # Removes a specified key from the hash.
154
+ def delete(key)
155
+ super(convert_key(key))
156
+ end
157
+
158
+ def stringify_keys!; self end
159
+ def stringify_keys; dup end
160
+ def symbolize_keys; to_hash.symbolize_keys end
161
+ def to_options!; self end
162
+
163
+ # Convert to a Hash with String keys.
164
+ def to_hash
165
+ Hash.new(default).merge!(self)
166
+ end
167
+
168
+ protected
169
+ def convert_key(key)
170
+ key.kind_of?(Symbol) ? key.to_s : key
171
+ end
172
+
173
+ def convert_value(value)
174
+ case value
175
+ when Hash
176
+ self.class.new_from_hash_copying_default(value)
177
+ when Array
178
+ value.collect { |e| e.is_a?(Hash) ? self.class.new_from_hash_copying_default(e) : e }
179
+ else
180
+ value
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+ HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess
metadata CHANGED
@@ -1,51 +1,63 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bson
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
4
+ hash: 7
5
+ prerelease:
5
6
  segments:
6
- - 1
7
- - 3
8
- - 1
9
- version: 1.3.1
7
+ - 1
8
+ - 4
9
+ - 0
10
+ version: 1.4.0
10
11
  platform: ruby
11
12
  authors:
12
- - Jim Menard
13
- - Mike Dirolf
14
- - Kyle Banker
13
+ - Jim Menard
14
+ - Mike Dirolf
15
+ - Kyle Banker
15
16
  autorequire:
16
17
  bindir: bin
17
18
  cert_chain: []
18
19
 
19
- date: 2011-05-11 00:00:00 -04:00
20
+ date: 2011-09-20 00:00:00 -04:00
20
21
  default_executable:
21
22
  dependencies: []
22
23
 
23
24
  description: A Ruby BSON implementation for MongoDB. For more information about Mongo, see http://www.mongodb.org. For more information on BSON, see http://www.bsonspec.org.
24
25
  email: mongodb-dev@googlegroups.com
25
26
  executables:
26
- - b2json
27
- - j2bson
27
+ - b2json
28
+ - j2bson
28
29
  extensions: []
29
30
 
30
31
  extra_rdoc_files: []
31
32
 
32
33
  files:
33
- - LICENSE.txt
34
- - lib/bson.rb
35
- - lib/bson/bson_ruby.rb
36
- - lib/bson/bson_c.rb
37
- - lib/bson/exceptions.rb
38
- - lib/bson/ordered_hash.rb
39
- - lib/bson/byte_buffer.rb
40
- - lib/bson/bson_java.rb
41
- - lib/bson/types/dbref.rb
42
- - lib/bson/types/code.rb
43
- - lib/bson/types/object_id.rb
44
- - lib/bson/types/binary.rb
45
- - lib/bson/types/timestamp.rb
46
- - lib/bson/types/min_max_keys.rb
47
- - bin/b2json
48
- - bin/j2bson
34
+ - LICENSE.txt
35
+ - lib/bson.rb
36
+ - lib/bson/bson_c.rb
37
+ - lib/bson/bson_java.rb
38
+ - lib/bson/bson_ruby.rb
39
+ - lib/bson/byte_buffer.rb
40
+ - lib/bson/exceptions.rb
41
+ - lib/bson/ordered_hash.rb
42
+ - lib/bson/types/binary.rb
43
+ - lib/bson/types/code.rb
44
+ - lib/bson/types/dbref.rb
45
+ - lib/bson/types/min_max_keys.rb
46
+ - lib/bson/types/object_id.rb
47
+ - lib/bson/types/timestamp.rb
48
+ - bin/b2json
49
+ - bin/j2bson
50
+ - test/bson/binary_test.rb
51
+ - test/bson/bson_string_test.rb
52
+ - test/bson/bson_test.rb
53
+ - test/bson/byte_buffer_test.rb
54
+ - test/bson/hash_with_indifferent_access_test.rb
55
+ - test/bson/json_test.rb
56
+ - test/bson/object_id_test.rb
57
+ - test/bson/ordered_hash_test.rb
58
+ - test/bson/test_helper.rb
59
+ - test/bson/timestamp_test.rb
60
+ - test/support/hash_with_indifferent_access.rb
49
61
  has_rdoc: true
50
62
  homepage: http://www.mongodb.org
51
63
  licenses: []
@@ -54,34 +66,41 @@ post_install_message:
54
66
  rdoc_options: []
55
67
 
56
68
  require_paths:
57
- - lib
69
+ - lib
58
70
  required_ruby_version: !ruby/object:Gem::Requirement
71
+ none: false
59
72
  requirements:
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- segments:
63
- - 0
64
- version: "0"
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
65
79
  required_rubygems_version: !ruby/object:Gem::Requirement
80
+ none: false
66
81
  requirements:
67
- - - ">="
68
- - !ruby/object:Gem::Version
69
- segments:
70
- - 0
71
- version: "0"
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ hash: 3
85
+ segments:
86
+ - 0
87
+ version: "0"
72
88
  requirements: []
73
89
 
74
90
  rubyforge_project:
75
- rubygems_version: 1.3.6
91
+ rubygems_version: 1.5.2
76
92
  signing_key:
77
93
  specification_version: 3
78
94
  summary: Ruby implementation of BSON
79
95
  test_files:
80
- - test/bson/byte_buffer_test.rb
81
- - test/bson/binary_test.rb
82
- - test/bson/object_id_test.rb
83
- - test/bson/json_test.rb
84
- - test/bson/timestamp_test.rb
85
- - test/bson/bson_test.rb
86
- - test/bson/ordered_hash_test.rb
87
- - test/bson/hash_with_indifferent_access_test.rb
96
+ - test/bson/binary_test.rb
97
+ - test/bson/bson_string_test.rb
98
+ - test/bson/bson_test.rb
99
+ - test/bson/byte_buffer_test.rb
100
+ - test/bson/hash_with_indifferent_access_test.rb
101
+ - test/bson/json_test.rb
102
+ - test/bson/object_id_test.rb
103
+ - test/bson/ordered_hash_test.rb
104
+ - test/bson/test_helper.rb
105
+ - test/bson/timestamp_test.rb
106
+ - test/support/hash_with_indifferent_access.rb