Fixed BSON behavior: now correctly writes _id first.

This commit is contained in:
Jim Menard 2009-01-27 16:26:42 -05:00
parent 1bbb9fb78f
commit 8a10a5d37d
4 changed files with 33 additions and 41 deletions

View File

@ -79,7 +79,17 @@ class BSON
# put in a placeholder for the total size
@buf.put_int(0)
obj.each {|k, v|
# Write key/value pairs. Always write _id first if it exists.
oid = obj.delete('_id') || obj.delete(:_id)
serialize_key_value('_id', oid) if oid
obj.each {|k, v| serialize_key_value(k, v) }
serialize_eoo_element(@buf)
@buf.put_int(@buf.size, 0)
self
end
def serialize_key_value(k, v)
type = bson_type(v, k)
case type
when STRING, CODE, SYMBOL
@ -112,10 +122,6 @@ class BSON
else
raise "unhandled type #{type}"
end
}
serialize_eoo_element(@buf)
@buf.put_int(@buf.size, 0)
self
end
def deserialize(buf=nil, parent=nil)
@ -338,20 +344,7 @@ class BSON
def serialize_object_element(buf, key, val, opcode=OBJECT)
buf.put(opcode)
self.class.serialize_cstr(buf, key)
buf.put_array(BSON.new.serialize(put_id_first(val)).to_a)
end
# For internal use only. Looks for '_id' or :_id key of val. If there is
# one, returns an OrderedHash where '_id' is first. If not, returns val.
def put_id_first(val)
oid = val.delete('_id') || val.delete(:_id)
if oid
h = OrderedHash.new
h['_id'] = oid
val.each { |k, v| h[k] = v }
val = h
end
val
buf.put_array(BSON.new.serialize(val).to_a)
end
def serialize_array_element(buf, key, val)

View File

@ -1,6 +1,6 @@
Gem::Specification.new do |s|
s.name = 'mongo'
s.version = '0.2.7'
s.version = '0.3.0'
s.platform = Gem::Platform::RUBY
s.summary = 'Simple pure-Ruby driver for the 10gen Mongo DB'
s.description = 'A pure-Ruby driver for the 10gen Mongo DB. For more information about Mongo, see http://www.mongodb.org.'

View File

@ -95,9 +95,6 @@ class BSONTest < Test::Unit::TestCase
assert_equal doc['date'].to_i, doc2['date'].to_i
end
def test_null
end
def test_dbref
oid = ObjectID.new
doc = {}
@ -125,17 +122,17 @@ class BSONTest < Test::Unit::TestCase
assert_equal 'binstring', doc2['bin']
end
# def test_binary_byte_buffer
# bb = ByteBuffer.new
# 10.times { |i| bb.put(i) }
# doc = {'bin' => bb}
# @b.serialize(doc)
# doc2 = @b.deserialize
def test_binary_byte_buffer
bb = ByteBuffer.new
10.times { |i| bb.put(i) }
doc = {'bin' => bb}
@b.serialize(doc)
doc2 = @b.deserialize
# doc2_bytes = []
# doc2['bin'].each_byte { |b| doc2_bytes << b }
# assert_equal bb.to_a, doc2_bytes
# end
doc2_bytes = []
doc2['bin'].each_byte { |b| doc2_bytes << b }
assert_equal bb.to_a, doc2_bytes
end
def test_undefined
doc = {'undef' => Undefined.new}
@ -145,19 +142,17 @@ class BSONTest < Test::Unit::TestCase
end
def test_put_id_first
val = {'a' => 'foo'}
assert_same val, @b.put_id_first(val)
val = OrderedHash.new
val['not_id'] = 1
val['_id'] = 2
id_first = @b.put_id_first(val)
assert_equal ['_id', 'not_id'], id_first.keys
roundtrip = @b.deserialize(@b.serialize(val).to_a)
assert_kind_of OrderedHash, roundtrip
assert_equal '_id', roundtrip.keys.first
val = {'a' => 'foo', 'b' => 'bar', :_id => 42, 'z' => 'hello'}
id_first = @b.put_id_first(val)
assert id_first.keys.include?('_id')
assert !id_first.keys.include?(:_id)
roundtrip = @b.deserialize(@b.serialize(val).to_a)
assert_kind_of OrderedHash, roundtrip
assert_equal '_id', roundtrip.keys.first
end
end

View File

@ -64,11 +64,15 @@ class DBTest < Test::Unit::TestCase
obj = coll.insert('name' => 'Fred', 'age' => 42)
row = coll.find({'name' => 'Fred'}, :limit => 1).next_object
oid = row.delete('_id')
assert_not_nil oid
assert_equal obj, row
oid = XGen::Mongo::Driver::ObjectID.new
obj = coll.insert('_id' => oid, 'name' => 'Barney', 'age' => 41)
row = coll.find({'name' => 'Barney'}, :limit => 1).next_object
db_oid = row.delete('_id')
assert_equal oid, db_oid
assert_equal obj, row
coll.clear