Handle unsupported types: Complex, Rational, and BigDecimal RUBY-85
This commit is contained in:
parent
bf7ffcfa82
commit
95d9d6b4f6
|
@ -274,7 +274,7 @@ static int write_element_allow_id(VALUE key, VALUE value, VALUE extra, int allow
|
||||||
case T_STRING:
|
case T_STRING:
|
||||||
{
|
{
|
||||||
if (strcmp(rb_class2name(RBASIC(value)->klass),
|
if (strcmp(rb_class2name(RBASIC(value)->klass),
|
||||||
"Mongo::Code") == 0) {
|
"Mongo::Code") == 0) {
|
||||||
buffer_position length_location, start_position, total_length;
|
buffer_position length_location, start_position, total_length;
|
||||||
int length;
|
int length;
|
||||||
write_name_and_type(buffer, key, 0x0F);
|
write_name_and_type(buffer, key, 0x0F);
|
||||||
|
@ -380,10 +380,14 @@ static int write_element_allow_id(VALUE key, VALUE value, VALUE extra, int allow
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (strcmp(cls, "DateTime") == 0 || strcmp(cls, "Date") == 0 || strcmp(cls, "ActiveSupport::TimeWithZone") == 0) {
|
if (strcmp(cls, "DateTime") == 0 || strcmp(cls, "Date") == 0 || strcmp(cls, "ActiveSupport::TimeWithZone") == 0) {
|
||||||
buffer_free(buffer);
|
buffer_free(buffer);
|
||||||
rb_raise(InvalidDocument,
|
rb_raise(InvalidDocument, "%s is not currently supported; use a UTC Time instance instead.", cls);
|
||||||
"Trying to serialize and instance of Date, DateTime, or TimeWithZone; the MongoDB Ruby driver currently supports Time objects only.",
|
break;
|
||||||
TYPE(value));
|
}
|
||||||
|
if(strcmp(cls, "Complex") == 0 || strcmp(cls, "Rational") == 0 || strcmp(cls, "BigDecimal") == 0) {
|
||||||
|
buffer_free(buffer);
|
||||||
|
rb_raise(InvalidDocument, "The Numeric type %s cannot be encoded as BSON; only Bignum, Fixnum, and Float are supported.", cls);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
buffer_free(buffer);
|
buffer_free(buffer);
|
||||||
rb_raise(InvalidDocument, "Cannot serialize an object of class %s into BSON.", cls);
|
rb_raise(InvalidDocument, "Cannot serialize an object of class %s into BSON.", cls);
|
||||||
|
@ -391,7 +395,6 @@ static int write_element_allow_id(VALUE key, VALUE value, VALUE extra, int allow
|
||||||
}
|
}
|
||||||
case T_DATA:
|
case T_DATA:
|
||||||
{
|
{
|
||||||
// TODO again, is this really the only way to do this?
|
|
||||||
const char* cls = rb_class2name(RBASIC(value)->klass);
|
const char* cls = rb_class2name(RBASIC(value)->klass);
|
||||||
if (strcmp(cls, "Time") == 0) {
|
if (strcmp(cls, "Time") == 0) {
|
||||||
double t = NUM2DBL(rb_funcall(value, rb_intern("to_f"), 0));
|
double t = NUM2DBL(rb_funcall(value, rb_intern("to_f"), 0));
|
||||||
|
@ -400,6 +403,14 @@ static int write_element_allow_id(VALUE key, VALUE value, VALUE extra, int allow
|
||||||
SAFE_WRITE(buffer, (const char*)&time_since_epoch, 8);
|
SAFE_WRITE(buffer, (const char*)&time_since_epoch, 8);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(strcmp(cls, "BigDecimal") == 0) {
|
||||||
|
buffer_free(buffer);
|
||||||
|
rb_raise(InvalidDocument, "The Numeric type %s cannot be encoded as BSON; only Bignum, Fixnum, and Float are supported.", cls);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buffer_free(buffer);
|
||||||
|
rb_raise(InvalidDocument, "Cannot serialize an object of class %s into BSON.", cls);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case T_REGEXP:
|
case T_REGEXP:
|
||||||
{
|
{
|
||||||
|
@ -441,7 +452,7 @@ static int write_element_allow_id(VALUE key, VALUE value, VALUE extra, int allow
|
||||||
{
|
{
|
||||||
const char* cls = rb_class2name(RBASIC(value)->klass);
|
const char* cls = rb_class2name(RBASIC(value)->klass);
|
||||||
buffer_free(buffer);
|
buffer_free(buffer);
|
||||||
rb_raise(InvalidDocument, "Cannot serialize an object of class %s into BSON.", cls);
|
rb_raise(InvalidDocument, "Cannot serialize an object of class %s (type %d) into BSON.", cls, TYPE(value));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -549,7 +549,7 @@ class BSON_RUBY
|
||||||
NULL
|
NULL
|
||||||
when Integer
|
when Integer
|
||||||
NUMBER_INT
|
NUMBER_INT
|
||||||
when Numeric
|
when Float
|
||||||
NUMBER
|
NUMBER
|
||||||
when ByteBuffer
|
when ByteBuffer
|
||||||
BINARY
|
BINARY
|
||||||
|
@ -577,15 +577,17 @@ class BSON_RUBY
|
||||||
MAXKEY
|
MAXKEY
|
||||||
when MinKey
|
when MinKey
|
||||||
MINKEY
|
MINKEY
|
||||||
|
when Numeric
|
||||||
|
raise InvalidDocument, "The Numeric type #{o.class} cannot be encoded as BSON; only Fixum, Bignum, and Float are supported."
|
||||||
when Date, DateTime
|
when Date, DateTime
|
||||||
raise InvalidDocument, "Trying to serialize an instance of #{o.class}; " +
|
raise InvalidDocument, "#{o.class} is not currently supported; " +
|
||||||
"the MongoDB Ruby driver currently supports Time objects only."
|
"use a UTC Time instance instead."
|
||||||
else
|
else
|
||||||
if defined?(ActiveSupport::TimeWithZone) && o.is_a?(ActiveSupport::TimeWithZone)
|
if defined?(ActiveSupport::TimeWithZone) && o.is_a?(ActiveSupport::TimeWithZone)
|
||||||
raise InvalidDocument, "Trying to serialize an instance of ActiveSupport::TimeWithZone; " +
|
raise InvalidDocument, "ActiveSupport::TimeWithZone is not currently supported; " +
|
||||||
"the MongoDB Ruby driver currently supports Time objects only."
|
"use a UTC Time instance instead."
|
||||||
else
|
else
|
||||||
raise InvalidDocument, "Unknown type of object: #{o.class.name}"
|
raise InvalidDocument, "#{o.class} isn't supported as a BSON type."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
# encoding:utf-8
|
# encoding:utf-8
|
||||||
require 'test/test_helper'
|
require 'test/test_helper'
|
||||||
|
require 'complex'
|
||||||
|
require 'bigdecimal'
|
||||||
|
require 'rational'
|
||||||
|
|
||||||
# Need to simulating this class
|
# Need to simulating this class
|
||||||
# without actually loading it.
|
# without actually loading it.
|
||||||
|
@ -197,7 +200,7 @@ class BSONTest < Test::Unit::TestCase
|
||||||
ensure
|
ensure
|
||||||
puts e.message
|
puts e.message
|
||||||
assert_equal InvalidDocument, e.class
|
assert_equal InvalidDocument, e.class
|
||||||
assert_match /Time objects only/, e.message
|
assert_match /UTC Time/, e.message
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -314,6 +317,20 @@ class BSONTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_invalid_numeric_types
|
||||||
|
[BigDecimal.new("1.0"), Complex.new(0, 1), Rational.new!(2, 3)].each do |type|
|
||||||
|
print type.class
|
||||||
|
doc = {"x" => type}
|
||||||
|
begin
|
||||||
|
BSON.serialize(doc)
|
||||||
|
rescue => e
|
||||||
|
ensure
|
||||||
|
assert_equal InvalidDocument, e.class
|
||||||
|
assert_match /Numeric type #{type.class}/, e.message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_do_not_change_original_object
|
def test_do_not_change_original_object
|
||||||
val = OrderedHash.new
|
val = OrderedHash.new
|
||||||
val['not_id'] = 1
|
val['not_id'] = 1
|
||||||
|
|
Loading…
Reference in New Issue