diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2015-02-01 13:02:56 +0900 |
---|---|---|
committer | Ryuta Kamizono <kamipo@gmail.com> | 2015-02-08 22:22:55 +0900 |
commit | f9839120379292cbc5da25f35311f457b08b44a8 (patch) | |
tree | 32d780f568088bbfa3519a0f8ca23137ca7d533a /activerecord/lib | |
parent | 31fafe0a3223b58e214c03c88a33d6ef4435f63c (diff) | |
download | rails-f9839120379292cbc5da25f35311f457b08b44a8.tar.gz rails-f9839120379292cbc5da25f35311f457b08b44a8.tar.bz2 rails-f9839120379292cbc5da25f35311f457b08b44a8.zip |
Fix rounding problem for PostgreSQL timestamp column
If timestamp column have the precision, it need to format according to
the precision of timestamp column.
Diffstat (limited to 'activerecord/lib')
3 files changed, 27 insertions, 19 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb index 1ce5f5ae58..c29692d6ca 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -917,18 +917,10 @@ module ActiveRecord end class MysqlDateTime < Type::DateTime # :nodoc: - def type_cast_for_database(value) - if value.acts_like?(:time) && value.respond_to?(:usec) - result = super.to_s(:db) - case precision - when 1..6 - "#{result}.#{sprintf("%0#{precision}d", value.usec / 10 ** (6 - precision))}" - else - result - end - else - super - end + private + + def has_precision? + precision || 0 end end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_time.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_time.rb index b9e7894e5c..2fe61eeb77 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_time.rb @@ -5,6 +5,15 @@ module ActiveRecord class DateTime < Type::DateTime # :nodoc: include Infinity + def type_cast_for_database(value) + if has_precision? && value.acts_like?(:time) && value.year <= 0 + bce_year = format("%04d", -value.year + 1) + super.sub(/^-?\d+/, bce_year) + " BC" + else + super + end + end + def cast_value(value) if value.is_a?(::String) case value diff --git a/activerecord/lib/active_record/type/date_time.rb b/activerecord/lib/active_record/type/date_time.rb index 5646ee61db..e8614b16e0 100644 --- a/activerecord/lib/active_record/type/date_time.rb +++ b/activerecord/lib/active_record/type/date_time.rb @@ -11,21 +11,28 @@ module ActiveRecord end def type_cast_for_database(value) + return super unless value.acts_like?(:time) + zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal - if value.acts_like?(:time) - if value.respond_to?(zone_conversion_method) - value.send(zone_conversion_method) - else - value - end + if value.respond_to?(zone_conversion_method) + value = value.send(zone_conversion_method) + end + + return value unless has_precision? + + result = value.to_s(:db) + if value.respond_to?(:usec) && (1..6).cover?(precision) + "#{result}.#{sprintf("%0#{precision}d", value.usec / 10 ** (6 - precision))}" else - super + result end end private + alias has_precision? precision + def cast_value(string) return string unless string.is_a?(::String) return if string.empty? |