Make sure _id gets written first when serializing BSON.

This commit is contained in:
Jim Menard 2009-01-26 09:02:18 -05:00
parent 4ef032b6f9
commit c65278afc7
2 changed files with 30 additions and 1 deletions

View File

@ -333,7 +333,20 @@ 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(val).to_a)
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
end
def serialize_array_element(buf, key, val)

View File

@ -132,4 +132,20 @@ class BSONTest < Test::Unit::TestCase
assert_kind_of Undefined, doc2['undef']
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
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)
end
end