support for long type in pure ruby [enc|dec]oder

This commit is contained in:
Mike Dirolf 2009-08-03 17:57:44 -04:00
parent cb52b24040
commit 0a60ad0d7b
3 changed files with 45 additions and 7 deletions

View File

@ -47,6 +47,7 @@ class BSON
CODE_W_SCOPE = 15
NUMBER_INT = 16
TIMESTAMP = 17
NUMBER_LONG = 18
MAXKEY = 127
if RUBY_VERSION >= '1.9'
@ -180,6 +181,9 @@ class BSON
when NUMBER_INT
key = deserialize_cstr(@buf)
doc[key] = deserialize_number_int_data(@buf)
when NUMBER_LONG
key = deserialize_cstr(@buf)
doc[key] = deserialize_number_long_data(@buf)
when OID
key = deserialize_cstr(@buf)
doc[key] = deserialize_oid_data(@buf)
@ -263,6 +267,12 @@ class BSON
unsigned >= 2**32 / 2 ? unsigned - 2**32 : unsigned
end
def deserialize_number_long_data(buf)
# same note as above applies here...
unsigned = buf.get_long
unsigned >= 2 ** 64 / 2 ? unsigned - 2**64 : unsigned
end
def deserialize_object_data(buf)
size = buf.get_int
buf.position -= 4
@ -394,17 +404,25 @@ class BSON
end
def serialize_number_element(buf, key, val, type)
if type == NUMBER
buf.put(type)
self.class.serialize_cstr(buf, key)
if type == NUMBER
buf.put_double(val)
else
if val > 2**32 / 2 - 1 or val < -2**32 / 2
raise RangeError.new("MongoDB can only handle 4-byte ints - try converting to a double before saving")
if val > 2**64 / 2 - 1 or val < -2**64 / 2
raise RangeError.new("MongoDB can only handle 8-byte ints")
end
if val > 2**32 / 2 - 1 or val < -2**32 / 2
buf.put(NUMBER_LONG)
self.class.serialize_cstr(buf, key)
buf.put_long(val)
else
buf.put(type)
self.class.serialize_cstr(buf, key)
buf.put_int(val)
end
end
end
def serialize_object_element(buf, key, val, check_keys, opcode=OBJECT)
buf.put(opcode)

View File

@ -215,18 +215,32 @@ class BSONTest < Test::Unit::TestCase
end
def test_overflow
doc = {"x" => 2**45}
doc = {"x" => 2**75}
assert_raise RangeError do
@b.serialize(doc)
end
doc = {"x" => 2147483647}
doc = {"x" => 9223372036854775}
assert_equal doc, @b.deserialize(@b.serialize(doc).to_a)
doc = {"x" => 9223372036854775807}
assert_equal doc, @b.deserialize(@b.serialize(doc).to_a)
doc["x"] = doc["x"] + 1
assert_raise RangeError do
@b.serialize(doc)
end
doc = {"x" => -9223372036854775}
assert_equal doc, @b.deserialize(@b.serialize(doc).to_a)
doc = {"x" => -9223372036854775808}
assert_equal doc, @b.deserialize(@b.serialize(doc).to_a)
doc["x"] = doc["x"] - 1
assert_raise RangeError do
@b.serialize(doc)
end
end
def test_do_not_change_original_object

View File

@ -639,6 +639,12 @@ class DBAPITest < Test::Unit::TestCase
assert_equal 2, @@coll.count
end
def test_save_long
@@coll.clear
@@coll.insert("x" => 9223372036854775807)
assert_equal 9223372036854775807, @@coll.find_first()["x"]
end
def test_find_by_oid
@@coll.clear