Merge branch 'master' of git://github.com/jimm/mongo-ruby-driver

This commit is contained in:
Adrian Madrid 2008-12-16 14:36:36 -07:00
commit 9392b7778a
5 changed files with 122 additions and 30 deletions

View File

@ -3,9 +3,9 @@
This is a simple pure-Ruby driver for the 10gen Mongo DB. For more information
about Mongo, see http://www.mongodb.org.
Note: this driver is still alpha quality. The API will change, as will the
Note: this driver is still alpha quality. The API will change, as may the
data saved to the database (especially primary key values). Do *_not_* use this
for any production data.
for any production data yet.
= Demo
@ -27,7 +27,7 @@ The tests assume that the Mongo database is running on the default port.
$ rake rdoc
Then open the file doc/index.html. (I need to figure out where to put this on
the Web, or even how to publish this to the Wiki at
the Web, or perhaps how to publish this to the Wiki at
http://github.com/jimm/mongo-ruby-driver/wikis automatically.)
@ -53,7 +53,7 @@ type
= To Do
* Tests that prove that this driver's ObjectID and Geir's Java version do the
same thing.
same thing. (I've done so manually.)
* Capped collection support.
@ -100,9 +100,3 @@ details.
See http://www.gnu.org/licenses/ for a copy of the GNU Affero General Public
License.
--
# Local Variables:
# mode:rdoc
# End:
++

View File

@ -3,35 +3,34 @@ require 'mongo/util/ordered_hash'
require 'mongo/objectid'
# See http://github.com/10gen/mongo/tree/master/db/jsobj.h
# and
class BSON
EOO = 0 # x
MAXKEY = -1 # x
NUMBER = 1 # x t
STRING = 2 # x t
OBJECT = 3 # x t
MINKEY = -1
EOO = 0
NUMBER = 1
STRING = 2
OBJECT = 3
ARRAY = 4
BINARY = 5
UNDEFINED = 6
OID = 7 # x
BOOLEAN = 8 # x t
DATE = 9 # x t
NULL = 10 # x t
OID = 7
BOOLEAN = 8
DATE = 9
NULL = 10
REGEX = 11
REF = 12
CODE = 13
SYMBOL = 14
CODE_W_SCOPE = 15
NUMBER_INT = 16
MAXKEY = 127
def self.serialize_cstr(buf, val)
buf.put_array(val.to_s.unpack("C*") + [0])
end
def initialize
@private_buf = ByteBuffer.new
@buf = ByteBuffer.new
end
@ -67,8 +66,10 @@ class BSON
serialize_date_element(@buf, k, v)
when NULL
serialize_null_element(@buf, k)
when BINARY, UNDEFINED, REF, SYMBOL, CODE_W_SCOPE
raise "unimplemented type #{type}"
else
raise "Unhandled Type #{type}"
raise "unhandled type #{type}"
end
}
serialize_eoo_element(@buf)
@ -76,15 +77,17 @@ class BSON
self
end
def deserialize(buf)
@buf = ByteBuffer.new(buf.to_a)
def deserialize(buf=nil)
# If buf is nil, use @buf, assumed to contain already-serialized BSON.
# This is only true during testing.
@buf = ByteBuffer.new(buf.to_a) if buf
@buf.rewind
@buf.get_int # eat message size
doc = {}
while @buf.more?
type = @buf.get
case type
when STRING
when STRING, CODE
key = deserialize_element_name(@buf)
doc[key] = deserialize_string_data(@buf)
when NUMBER
@ -302,7 +305,7 @@ class BSON
when XGen::Mongo::Driver::ObjectID
OID
when true, false
Boolean
BOOLEAN
when Time
DATE
when Hash

View File

@ -49,8 +49,14 @@ class ByteBuffer
@cursor += array.length
end
def put_int(i, offset=nil)
put_array([i].pack(@int_pack_order).split(//).collect{|c| c[0]}, offset)
if RUBY_VERSION >= '1.9'
def put_int(i, offset=nil)
put_array([i].pack(@int_pack_order).split(//).collect{|c| c.bytes.first}, offset)
end
else
def put_int(i, offset=nil)
put_array([i].pack(@int_pack_order).split(//).collect{|c| c[0]}, offset)
end
end
def put_long(i, offset=nil)
@ -64,8 +70,14 @@ class ByteBuffer
end
end
def put_double(d, offset=nil)
put_array([d].pack(@double_pack_order).split(//), offset)
if RUBY_VERSION >= '1.9'
def put_double(d, offset=nil)
put_array([d].pack(@double_pack_order).split(//).collect{|c| c.bytes.first}, offset)
end
else
def put_double(d, offset=nil)
put_array([d].pack(@double_pack_order).split(//).collect{|c| c[0]}, offset)
end
end
# If +size+ == 1, returns one byte. Else returns array of bytes of length

77
tests/test_bson.rb Normal file
View File

@ -0,0 +1,77 @@
$LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
require 'mongo'
require 'test/unit'
# NOTE: assumes Mongo is running
class BSONTest < Test::Unit::TestCase
def setup
@b = BSON.new
end
def test_string
doc = {'doc' => 'hello, world'}
@b.serialize(doc)
assert_equal doc, @b.deserialize
end
def test_code
doc = {'$where' => 'this.a.b < this.b'}
@b.serialize(doc)
assert_equal doc, @b.deserialize
end
def test_number
doc = {'doc' => 41.99}
@b.serialize(doc)
assert_equal doc, @b.deserialize
end
def test_int
doc = {'doc' => 42}
@b.serialize(doc)
assert_equal doc, @b.deserialize
end
def test_object
doc = {'doc' => {'age' => 42, 'name' => 'Spongebob', 'shoe_size' => 9.5}}
@b.serialize(doc)
assert_equal doc, @b.deserialize
end
def test_oid
doc = {'doc' => XGen::Mongo::Driver::ObjectID.new}
@b.serialize(doc)
assert_equal doc, @b.deserialize
end
def test_array
doc = {'doc' => [1, 2, 'a', 'b']}
@b.serialize(doc)
assert_equal doc, @b.deserialize
end
def test_regex
doc = {'doc' => /foobar/i}
@b.serialize(doc)
assert_equal doc, @b.deserialize
end
def test_boolean
doc = {'doc' => true}
@b.serialize(doc)
assert_equal doc, @b.deserialize
end
def test_date
doc = {'date' => Time.now}
@b.serialize(doc)
doc2 = @b.deserialize
# Mongo only stores seconds, so comparing raw Time objects will fail
# because the fractional seconds will be different.
assert_equal doc['date'].to_i, doc2['date'].to_i
end
def test_null
end
end

View File

@ -32,6 +32,12 @@ class ByteBufferTest < Test::Unit::TestCase
assert_equal 1027, @buf.get_long
end
def test_get_double
@buf.put_double 41.2
@buf.rewind
assert_equal 41.2, @buf.get_double
end
def test_rewrite
@buf.put_int(0)
@buf.rewind