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
|
CODE_W_SCOPE = 15
|
||||||
NUMBER_INT = 16
|
NUMBER_INT = 16
|
||||||
TIMESTAMP = 17
|
TIMESTAMP = 17
|
||||||
|
NUMBER_LONG = 18
|
||||||
MAXKEY = 127
|
MAXKEY = 127
|
||||||
|
|
||||||
if RUBY_VERSION >= '1.9'
|
if RUBY_VERSION >= '1.9'
|
||||||
|
@ -180,6 +181,9 @@ class BSON
|
||||||
when NUMBER_INT
|
when NUMBER_INT
|
||||||
key = deserialize_cstr(@buf)
|
key = deserialize_cstr(@buf)
|
||||||
doc[key] = deserialize_number_int_data(@buf)
|
doc[key] = deserialize_number_int_data(@buf)
|
||||||
|
when NUMBER_LONG
|
||||||
|
key = deserialize_cstr(@buf)
|
||||||
|
doc[key] = deserialize_number_long_data(@buf)
|
||||||
when OID
|
when OID
|
||||||
key = deserialize_cstr(@buf)
|
key = deserialize_cstr(@buf)
|
||||||
doc[key] = deserialize_oid_data(@buf)
|
doc[key] = deserialize_oid_data(@buf)
|
||||||
|
@ -263,6 +267,12 @@ class BSON
|
||||||
unsigned >= 2**32 / 2 ? unsigned - 2**32 : unsigned
|
unsigned >= 2**32 / 2 ? unsigned - 2**32 : unsigned
|
||||||
end
|
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)
|
def deserialize_object_data(buf)
|
||||||
size = buf.get_int
|
size = buf.get_int
|
||||||
buf.position -= 4
|
buf.position -= 4
|
||||||
|
@ -394,17 +404,25 @@ class BSON
|
||||||
end
|
end
|
||||||
|
|
||||||
def serialize_number_element(buf, key, val, type)
|
def serialize_number_element(buf, key, val, type)
|
||||||
|
if type == NUMBER
|
||||||
buf.put(type)
|
buf.put(type)
|
||||||
self.class.serialize_cstr(buf, key)
|
self.class.serialize_cstr(buf, key)
|
||||||
if type == NUMBER
|
|
||||||
buf.put_double(val)
|
buf.put_double(val)
|
||||||
else
|
else
|
||||||
if val > 2**32 / 2 - 1 or val < -2**32 / 2
|
if val > 2**64 / 2 - 1 or val < -2**64 / 2
|
||||||
raise RangeError.new("MongoDB can only handle 4-byte ints - try converting to a double before saving")
|
raise RangeError.new("MongoDB can only handle 8-byte ints")
|
||||||
end
|
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)
|
buf.put_int(val)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def serialize_object_element(buf, key, val, check_keys, opcode=OBJECT)
|
def serialize_object_element(buf, key, val, check_keys, opcode=OBJECT)
|
||||||
buf.put(opcode)
|
buf.put(opcode)
|
||||||
|
|
|
@ -215,18 +215,32 @@ class BSONTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_overflow
|
def test_overflow
|
||||||
doc = {"x" => 2**45}
|
doc = {"x" => 2**75}
|
||||||
assert_raise RangeError do
|
assert_raise RangeError do
|
||||||
@b.serialize(doc)
|
@b.serialize(doc)
|
||||||
end
|
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)
|
assert_equal doc, @b.deserialize(@b.serialize(doc).to_a)
|
||||||
|
|
||||||
doc["x"] = doc["x"] + 1
|
doc["x"] = doc["x"] + 1
|
||||||
assert_raise RangeError do
|
assert_raise RangeError do
|
||||||
@b.serialize(doc)
|
@b.serialize(doc)
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
def test_do_not_change_original_object
|
def test_do_not_change_original_object
|
||||||
|
|
|
@ -639,6 +639,12 @@ class DBAPITest < Test::Unit::TestCase
|
||||||
assert_equal 2, @@coll.count
|
assert_equal 2, @@coll.count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_save_long
|
||||||
|
@@coll.clear
|
||||||
|
@@coll.insert("x" => 9223372036854775807)
|
||||||
|
assert_equal 9223372036854775807, @@coll.find_first()["x"]
|
||||||
|
end
|
||||||
|
|
||||||
def test_find_by_oid
|
def test_find_by_oid
|
||||||
@@coll.clear
|
@@coll.clear
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue