diff options
Diffstat (limited to 'activerecord/lib/active_record/type/integer.rb')
-rw-r--r-- | activerecord/lib/active_record/type/integer.rb | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/activerecord/lib/active_record/type/integer.rb b/activerecord/lib/active_record/type/integer.rb index 08477d1303..2a1b04ac7f 100644 --- a/activerecord/lib/active_record/type/integer.rb +++ b/activerecord/lib/active_record/type/integer.rb @@ -1,13 +1,37 @@ module ActiveRecord module Type class Integer < Value # :nodoc: - include Numeric + include Helpers::Numeric + + # Column storage size in bytes. + # 4 bytes means a MySQL int or Postgres integer as opposed to smallint etc. + DEFAULT_LIMIT = 4 + + def initialize(*) + super + @range = min_value...max_value + end def type :integer end - alias type_cast_for_database type_cast + def deserialize(value) + return if value.nil? + value.to_i + end + + def serialize(value) + result = cast(value) + if result + ensure_in_range(result) + end + result + end + + protected + + attr_reader :range private @@ -15,9 +39,25 @@ module ActiveRecord case value when true then 1 when false then 0 - else value.to_i rescue nil + else + value.to_i rescue nil + end + end + + def ensure_in_range(value) + unless range.cover?(value) + raise RangeError, "#{value} is out of range for #{self.class} with limit #{limit || DEFAULT_LIMIT}" end end + + def max_value + limit = self.limit || DEFAULT_LIMIT + 1 << (limit * 8 - 1) # 8 bits per byte with one bit for sign + end + + def min_value + -max_value + end end end end |