diff options
author | Sean Griffin <sean@thoughtbot.com> | 2015-02-07 14:34:46 -0700 |
---|---|---|
committer | Sean Griffin <sean@thoughtbot.com> | 2015-02-07 14:34:46 -0700 |
commit | c4ef73affdc67efb02ca369326aaaaab3fd94d21 (patch) | |
tree | 060ac064cd881b52f9179f7417c7f253779f750f /activerecord | |
parent | 7e93e33c1980ea3d08cec9708d2737f1c8d0a10a (diff) | |
download | rails-c4ef73affdc67efb02ca369326aaaaab3fd94d21.tar.gz rails-c4ef73affdc67efb02ca369326aaaaab3fd94d21.tar.bz2 rails-c4ef73affdc67efb02ca369326aaaaab3fd94d21.zip |
Move non-type objects into the `Type::Helpers` namespace
The type code is actually quite accessible, and I'm planning to
encourage people to look at the files in the `type` folder to learn more
about how it works. This will help reduce the noise from code that is
less about type casting, and more about random AR nonsense.
Diffstat (limited to 'activerecord')
19 files changed, 110 insertions, 104 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb index 0a0a7fdbb3..2608a2abab 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb @@ -3,7 +3,7 @@ module ActiveRecord module PostgreSQL module OID # :nodoc: class Array < Type::Value # :nodoc: - include Type::Mutable + include Type::Helpers::Mutable # Loads pg_array_parser if available. String parsing can be # performed quicker by a native extension, which will not create diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb index be4525c94f..b46e50c865 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb @@ -3,7 +3,7 @@ module ActiveRecord module PostgreSQL module OID # :nodoc: class Hstore < Type::Value # :nodoc: - include Type::Mutable + include Type::Helpers::Mutable def type :hstore diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/json.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/json.rb index 7dadc09a44..13dd037314 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/json.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/json.rb @@ -3,7 +3,7 @@ module ActiveRecord module PostgreSQL module OID # :nodoc: class Json < Type::Value # :nodoc: - include Type::Mutable + include Type::Helpers::Mutable def type :json diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/point.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/point.rb index bac8b01d6b..4084725ed7 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/point.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/point.rb @@ -3,7 +3,7 @@ module ActiveRecord module PostgreSQL module OID # :nodoc: class Point < Type::Value # :nodoc: - include Type::Mutable + include Type::Helpers::Mutable def type :point diff --git a/activerecord/lib/active_record/type.rb b/activerecord/lib/active_record/type.rb index 1f978a17c5..f18b076d58 100644 --- a/activerecord/lib/active_record/type.rb +++ b/activerecord/lib/active_record/type.rb @@ -1,7 +1,4 @@ require 'active_record/type/helpers' -require 'active_record/type/mutable' -require 'active_record/type/numeric' -require 'active_record/type/time_value' require 'active_record/type/value' require 'active_record/type/big_integer' diff --git a/activerecord/lib/active_record/type/date_time.rb b/activerecord/lib/active_record/type/date_time.rb index 922f0d8fef..5646ee61db 100644 --- a/activerecord/lib/active_record/type/date_time.rb +++ b/activerecord/lib/active_record/type/date_time.rb @@ -1,7 +1,7 @@ module ActiveRecord module Type class DateTime < Value # :nodoc: - include TimeValue + include Helpers::TimeValue include Helpers::AcceptsMultiparameterTime.new( defaults: { 4 => 0, 5 => 0 } ) diff --git a/activerecord/lib/active_record/type/decimal.rb b/activerecord/lib/active_record/type/decimal.rb index 7b2bee2c42..867b5f75c7 100644 --- a/activerecord/lib/active_record/type/decimal.rb +++ b/activerecord/lib/active_record/type/decimal.rb @@ -1,7 +1,7 @@ module ActiveRecord module Type class Decimal < Value # :nodoc: - include Numeric + include Helpers::Numeric def type :decimal diff --git a/activerecord/lib/active_record/type/float.rb b/activerecord/lib/active_record/type/float.rb index 42eb44b9a9..0a9088e0a1 100644 --- a/activerecord/lib/active_record/type/float.rb +++ b/activerecord/lib/active_record/type/float.rb @@ -1,7 +1,7 @@ module ActiveRecord module Type class Float < Value # :nodoc: - include Numeric + include Helpers::Numeric def type :float diff --git a/activerecord/lib/active_record/type/helpers.rb b/activerecord/lib/active_record/type/helpers.rb index c22869c330..634d417d13 100644 --- a/activerecord/lib/active_record/type/helpers.rb +++ b/activerecord/lib/active_record/type/helpers.rb @@ -1 +1,4 @@ require 'active_record/type/helpers/accepts_multiparameter_time' +require 'active_record/type/helpers/numeric' +require 'active_record/type/helpers/mutable' +require 'active_record/type/helpers/time_value' diff --git a/activerecord/lib/active_record/type/helpers/accepts_multiparameter_time.rb b/activerecord/lib/active_record/type/helpers/accepts_multiparameter_time.rb index c528d410d3..640943c5e9 100644 --- a/activerecord/lib/active_record/type/helpers/accepts_multiparameter_time.rb +++ b/activerecord/lib/active_record/type/helpers/accepts_multiparameter_time.rb @@ -1,7 +1,7 @@ module ActiveRecord module Type module Helpers - class AcceptsMultiparameterTime < Module + class AcceptsMultiparameterTime < Module # :nodoc: def initialize(defaults: {}) define_method(:type_cast_from_user) do |value| if value.is_a?(Hash) diff --git a/activerecord/lib/active_record/type/helpers/mutable.rb b/activerecord/lib/active_record/type/helpers/mutable.rb new file mode 100644 index 0000000000..dc37f4a885 --- /dev/null +++ b/activerecord/lib/active_record/type/helpers/mutable.rb @@ -0,0 +1,18 @@ +module ActiveRecord + module Type + module Helpers + module Mutable # :nodoc: + def type_cast_from_user(value) + type_cast_from_database(type_cast_for_database(value)) + end + + # +raw_old_value+ will be the `_before_type_cast` version of the + # value (likely a string). +new_value+ will be the current, type + # cast value. + def changed_in_place?(raw_old_value, new_value) + raw_old_value != type_cast_for_database(new_value) + end + end + end + end +end diff --git a/activerecord/lib/active_record/type/helpers/numeric.rb b/activerecord/lib/active_record/type/helpers/numeric.rb new file mode 100644 index 0000000000..86888eef75 --- /dev/null +++ b/activerecord/lib/active_record/type/helpers/numeric.rb @@ -0,0 +1,38 @@ +module ActiveRecord + module Type + module Helpers + module Numeric # :nodoc: + def number? + true + end + + def type_cast(value) + value = case value + when true then 1 + when false then 0 + when ::String then value.presence + else value + end + super(value) + end + + def changed?(old_value, _new_value, new_value_before_type_cast) # :nodoc: + super || number_to_non_number?(old_value, new_value_before_type_cast) + end + + private + + def number_to_non_number?(old_value, new_value_before_type_cast) + old_value != nil && non_numeric_string?(new_value_before_type_cast) + end + + def non_numeric_string?(value) + # 'wibble'.to_i will give zero, we want to make sure + # that we aren't marking int zero to string zero as + # changed. + value.to_s !~ /\A-?\d+\.?\d*\z/ + end + end + end + end +end diff --git a/activerecord/lib/active_record/type/helpers/time_value.rb b/activerecord/lib/active_record/type/helpers/time_value.rb new file mode 100644 index 0000000000..6e14c3a9b5 --- /dev/null +++ b/activerecord/lib/active_record/type/helpers/time_value.rb @@ -0,0 +1,40 @@ +module ActiveRecord + module Type + module Helpers + module TimeValue # :nodoc: + def type_cast_for_schema(value) + "'#{value.to_s(:db)}'" + end + + def user_input_in_time_zone(value) + value.in_time_zone + end + + private + + def new_time(year, mon, mday, hour, min, sec, microsec, offset = nil) + # Treat 0000-00-00 00:00:00 as nil. + return if year.nil? || (year == 0 && mon == 0 && mday == 0) + + if offset + time = ::Time.utc(year, mon, mday, hour, min, sec, microsec) rescue nil + return unless time + + time -= offset + Base.default_timezone == :utc ? time : time.getlocal + else + ::Time.public_send(Base.default_timezone, year, mon, mday, hour, min, sec, microsec) rescue nil + end + end + + # Doesn't handle time zones. + def fast_string_to_time(string) + if string =~ ConnectionAdapters::Column::Format::ISO_DATETIME + microsec = ($7.to_r * 1_000_000).to_i + new_time $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, microsec + end + end + end + end + end +end diff --git a/activerecord/lib/active_record/type/integer.rb b/activerecord/lib/active_record/type/integer.rb index 90ca9f88da..2ab2402dfd 100644 --- a/activerecord/lib/active_record/type/integer.rb +++ b/activerecord/lib/active_record/type/integer.rb @@ -1,7 +1,7 @@ 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. diff --git a/activerecord/lib/active_record/type/mutable.rb b/activerecord/lib/active_record/type/mutable.rb deleted file mode 100644 index 066617ea59..0000000000 --- a/activerecord/lib/active_record/type/mutable.rb +++ /dev/null @@ -1,16 +0,0 @@ -module ActiveRecord - module Type - module Mutable # :nodoc: - def type_cast_from_user(value) - type_cast_from_database(type_cast_for_database(value)) - end - - # +raw_old_value+ will be the `_before_type_cast` version of the - # value (likely a string). +new_value+ will be the current, type - # cast value. - def changed_in_place?(raw_old_value, new_value) - raw_old_value != type_cast_for_database(new_value) - end - end - end -end diff --git a/activerecord/lib/active_record/type/numeric.rb b/activerecord/lib/active_record/type/numeric.rb deleted file mode 100644 index 674f996f38..0000000000 --- a/activerecord/lib/active_record/type/numeric.rb +++ /dev/null @@ -1,36 +0,0 @@ -module ActiveRecord - module Type - module Numeric # :nodoc: - def number? - true - end - - def type_cast(value) - value = case value - when true then 1 - when false then 0 - when ::String then value.presence - else value - end - super(value) - end - - def changed?(old_value, _new_value, new_value_before_type_cast) # :nodoc: - super || number_to_non_number?(old_value, new_value_before_type_cast) - end - - private - - def number_to_non_number?(old_value, new_value_before_type_cast) - old_value != nil && non_numeric_string?(new_value_before_type_cast) - end - - def non_numeric_string?(value) - # 'wibble'.to_i will give zero, we want to make sure - # that we aren't marking int zero to string zero as - # changed. - value.to_s !~ /\A-?\d+\.?\d*\z/ - end - end - end -end diff --git a/activerecord/lib/active_record/type/serialized.rb b/activerecord/lib/active_record/type/serialized.rb index c1ca5fd936..6c6c520048 100644 --- a/activerecord/lib/active_record/type/serialized.rb +++ b/activerecord/lib/active_record/type/serialized.rb @@ -1,7 +1,7 @@ module ActiveRecord module Type class Serialized < DelegateClass(Type::Value) # :nodoc: - include Mutable + include Helpers::Mutable attr_reader :subtype, :coder diff --git a/activerecord/lib/active_record/type/time.rb b/activerecord/lib/active_record/type/time.rb index 930fb69da0..19a10021bc 100644 --- a/activerecord/lib/active_record/type/time.rb +++ b/activerecord/lib/active_record/type/time.rb @@ -1,7 +1,7 @@ module ActiveRecord module Type class Time < Value # :nodoc: - include TimeValue + include Helpers::TimeValue include Helpers::AcceptsMultiparameterTime.new( defaults: { 1 => 1970, 2 => 1, 3 => 1, 4 => 0, 5 => 0 } ) diff --git a/activerecord/lib/active_record/type/time_value.rb b/activerecord/lib/active_record/type/time_value.rb deleted file mode 100644 index 53188d4d69..0000000000 --- a/activerecord/lib/active_record/type/time_value.rb +++ /dev/null @@ -1,38 +0,0 @@ -module ActiveRecord - module Type - module TimeValue # :nodoc: - def type_cast_for_schema(value) - "'#{value.to_s(:db)}'" - end - - def user_input_in_time_zone(value) - value.in_time_zone - end - - private - - def new_time(year, mon, mday, hour, min, sec, microsec, offset = nil) - # Treat 0000-00-00 00:00:00 as nil. - return if year.nil? || (year == 0 && mon == 0 && mday == 0) - - if offset - time = ::Time.utc(year, mon, mday, hour, min, sec, microsec) rescue nil - return unless time - - time -= offset - Base.default_timezone == :utc ? time : time.getlocal - else - ::Time.public_send(Base.default_timezone, year, mon, mday, hour, min, sec, microsec) rescue nil - end - end - - # Doesn't handle time zones. - def fast_string_to_time(string) - if string =~ ConnectionAdapters::Column::Format::ISO_DATETIME - microsec = ($7.to_r * 1_000_000).to_i - new_time $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, microsec - end - end - end - end -end |