Pass parent, name, and database to DBRef constructor when deserializing BSON

This commit is contained in:
Jim Menard 2009-01-09 15:22:10 -05:00
parent a772e222ee
commit 97fa97bd2c
4 changed files with 24 additions and 17 deletions

View File

@ -167,7 +167,7 @@ module XGen
buf.put_array(@db.socket.recv(size-4).unpack("C*"), 4) buf.put_array(@db.socket.recv(size-4).unpack("C*"), 4)
@n_remaining -= 1 @n_remaining -= 1
buf.rewind buf.rewind
BSON.new.deserialize(buf) BSON.new(@db).deserialize(buf)
end end
def to_s def to_s

View File

@ -46,7 +46,9 @@ class BSON
buf.put_array(val.to_s.unpack("C*") + [0]) buf.put_array(val.to_s.unpack("C*") + [0])
end end
def initialize def initialize(db=nil)
# db is only needed during deserialization when the data contains a DBRef
@db = db
@buf = ByteBuffer.new @buf = ByteBuffer.new
end end
@ -96,7 +98,7 @@ class BSON
self self
end end
def deserialize(buf=nil) def deserialize(buf=nil, parent=nil)
# If buf is nil, use @buf, assumed to contain already-serialized BSON. # If buf is nil, use @buf, assumed to contain already-serialized BSON.
# This is only true during testing. # This is only true during testing.
@buf = ByteBuffer.new(buf.to_a) if buf @buf = ByteBuffer.new(buf.to_a) if buf
@ -120,13 +122,13 @@ class BSON
doc[key] = deserialize_oid_data(@buf) doc[key] = deserialize_oid_data(@buf)
when ARRAY when ARRAY
key = deserialize_cstr(@buf) key = deserialize_cstr(@buf)
doc[key] = deserialize_array_data(@buf) doc[key] = deserialize_array_data(@buf, doc)
when REGEX when REGEX
key = deserialize_cstr(@buf) key = deserialize_cstr(@buf)
doc[key] = deserialize_regex_data(@buf) doc[key] = deserialize_regex_data(@buf)
when OBJECT when OBJECT
key = deserialize_cstr(@buf) key = deserialize_cstr(@buf)
doc[key] = deserialize_object_data(@buf) doc[key] = deserialize_object_data(@buf, doc)
when BOOLEAN when BOOLEAN
key = deserialize_cstr(@buf) key = deserialize_cstr(@buf)
doc[key] = deserialize_boolean_data(@buf) doc[key] = deserialize_boolean_data(@buf)
@ -138,7 +140,7 @@ class BSON
doc[key] = nil doc[key] = nil
when REF when REF
key = deserialize_cstr(@buf) key = deserialize_cstr(@buf)
doc[key] = deserialize_dbref_data(@buf) doc[key] = deserialize_dbref_data(@buf, key, parent)
when BINARY, SYMBOL, CODE_W_SCOPE when BINARY, SYMBOL, CODE_W_SCOPE
# TODO # TODO
raise "unimplemented type #{type}" raise "unimplemented type #{type}"
@ -183,14 +185,14 @@ class BSON
buf.get_int buf.get_int
end end
def deserialize_object_data(buf) def deserialize_object_data(buf, parent)
size = buf.get_int size = buf.get_int
buf.position -= 4 buf.position -= 4
BSON.new.deserialize(buf.get(size)) BSON.new(@db).deserialize(buf.get(size), parent)
end end
def deserialize_array_data(buf) def deserialize_array_data(buf, parent)
h = deserialize_object_data(buf) h = deserialize_object_data(buf, parent)
a = [] a = []
h.each { |k, v| a[k.to_i] = v } h.each { |k, v| a[k.to_i] = v }
a a
@ -216,12 +218,10 @@ class BSON
XGen::Mongo::Driver::ObjectID.new(buf.get(12)) XGen::Mongo::Driver::ObjectID.new(buf.get(12))
end end
def deserialize_dbref_data(buf) def deserialize_dbref_data(buf, key, parent)
ns = deserialize_cstr(buf) ns = deserialize_cstr(buf)
oid = deserialize_oid_data(buf) oid = deserialize_oid_data(buf)
# TODO fix parent, field_name, db of DBRef. Does that need to be done here XGen::Mongo::Driver::DBRef.new(parent, key, @db, ns, oid)
# or by the caller?
XGen::Mongo::Driver::DBRef.new(nil, nil, nil, ns, oid)
end end
def serialize_eoo_element(buf) def serialize_eoo_element(buf)

View File

@ -8,6 +8,9 @@ class BSONTest < Test::Unit::TestCase
include XGen::Mongo::Driver include XGen::Mongo::Driver
def setup def setup
# We don't pass a DB to the constructor, even though we are about to test
# deserialization. This means that when we deserialize, any DBRefs will
# have nil @db ivars. That's fine for now.
@b = BSON.new @b = BSON.new
end end
@ -79,7 +82,8 @@ class BSONTest < Test::Unit::TestCase
def test_dbref def test_dbref
oid = ObjectID.new oid = ObjectID.new
doc = {'dbref' => DBRef.new(nil, nil, nil, 'namespace', oid)} doc = {}
doc['dbref'] = DBRef.new(doc, 'dbref', nil, 'namespace', oid)
@b.serialize(doc) @b.serialize(doc)
doc2 = @b.deserialize doc2 = @b.deserialize
assert_equal 'namespace', doc2['dbref'].namespace assert_equal 'namespace', doc2['dbref'].namespace

View File

@ -115,8 +115,11 @@ class RoundTripTest < Test::Unit::TestCase
assert_equal bson.length, bson_from_ruby.length assert_equal bson.length, bson_from_ruby.length
assert_equal bson, bson_from_ruby assert_equal bson, bson_from_ruby
# Turn those BSON bytes back into a Ruby object # Turn those BSON bytes back into a Ruby object.
obj_from_bson = BSON.new.deserialize(ByteBuffer.new(bson_from_ruby)) #
# We're passing a nil db to the contructor here, but that's OK because
# the BSON bytes don't contain the db object in any case.
obj_from_bson = BSON.new(nil).deserialize(ByteBuffer.new(bson_from_ruby))
assert_kind_of OrderedHash, obj_from_bson assert_kind_of OrderedHash, obj_from_bson
# Turn that Ruby object into BSON and compare it to the original BSON # Turn that Ruby object into BSON and compare it to the original BSON