Make sure _id gets written first when serializing BSON.
This commit is contained in:
parent
4ef032b6f9
commit
c65278afc7
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue