support for long type in pure ruby [enc|dec]oder
This commit is contained in:
parent
cb52b24040
commit
0a60ad0d7b
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue