diff options
Diffstat (limited to 'activerecord/lib')
-rw-r--r-- | activerecord/lib/active_record/core.rb | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation/finder_methods.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/type.rb | 1 | ||||
-rw-r--r-- | activerecord/lib/active_record/type/big_integer.rb | 13 | ||||
-rw-r--r-- | activerecord/lib/active_record/type/decimal_without_scale.rb | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/type/integer.rb | 25 |
6 files changed, 46 insertions, 3 deletions
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index a0382f99e6..952aeaa703 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -155,6 +155,8 @@ module ActiveRecord raise RecordNotFound, "Couldn't find #{name} with '#{primary_key}'=#{id}" end record + rescue RangeError + raise RecordNotFound, "Couldn't find #{name} with an out of range value for '#{primary_key}'" end def find_by(*args) @@ -185,6 +187,8 @@ module ActiveRecord s.execute(hash.values, self, connection).first rescue TypeError => e raise ActiveRecord::StatementInvalid.new(e.message, e) + rescue RangeError + nil end end diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index ddb392a6d4..145b7378cf 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -433,6 +433,8 @@ module ActiveRecord else find_some(ids) end + rescue RangeError + raise RecordNotFound, "Couldn't find #{@klass.name} with an out of range ID" end def find_one(id) diff --git a/activerecord/lib/active_record/type.rb b/activerecord/lib/active_record/type.rb index e3d6c5957e..e5acbbb6b3 100644 --- a/activerecord/lib/active_record/type.rb +++ b/activerecord/lib/active_record/type.rb @@ -4,6 +4,7 @@ require 'active_record/type/numeric' require 'active_record/type/time_value' require 'active_record/type/value' +require 'active_record/type/big_integer' require 'active_record/type/binary' require 'active_record/type/boolean' require 'active_record/type/date' diff --git a/activerecord/lib/active_record/type/big_integer.rb b/activerecord/lib/active_record/type/big_integer.rb new file mode 100644 index 0000000000..0c72d8914f --- /dev/null +++ b/activerecord/lib/active_record/type/big_integer.rb @@ -0,0 +1,13 @@ +require 'active_record/type/integer' + +module ActiveRecord + module Type + class BigInteger < Integer # :nodoc: + private + + def max_value + ::Float::INFINITY + end + end + end +end diff --git a/activerecord/lib/active_record/type/decimal_without_scale.rb b/activerecord/lib/active_record/type/decimal_without_scale.rb index cabdcecdd7..ff5559e300 100644 --- a/activerecord/lib/active_record/type/decimal_without_scale.rb +++ b/activerecord/lib/active_record/type/decimal_without_scale.rb @@ -1,8 +1,8 @@ -require 'active_record/type/integer' +require 'active_record/type/big_integer' module ActiveRecord module Type - class DecimalWithoutScale < Integer # :nodoc: + class DecimalWithoutScale < BigInteger # :nodoc: def type :decimal end diff --git a/activerecord/lib/active_record/type/integer.rb b/activerecord/lib/active_record/type/integer.rb index 08477d1303..d69e5b3f28 100644 --- a/activerecord/lib/active_record/type/integer.rb +++ b/activerecord/lib/active_record/type/integer.rb @@ -3,21 +3,44 @@ module ActiveRecord class Integer < Value # :nodoc: include Numeric + def initialize(*) + super + @range = -max_value...max_value + end + def type :integer end alias type_cast_for_database type_cast + protected + + attr_reader :range + private def cast_value(value) case value when true then 1 when false then 0 - else value.to_i rescue nil + else + result = value.to_i rescue nil + ensure_in_range(result) if result + result end end + + def ensure_in_range(value) + unless range.cover?(value) + raise RangeError, "#{value} is too large for #{self.class} with limit #{limit || 4}" + end + end + + def max_value + limit = self.limit || 4 + 1 << (limit * 8 - 1) # 8 bits per byte with one bit for sign + end end end end |