From 22c27ae31f1b7c3a4e3b5cbcb4571c6be5e527e8 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Thu, 22 May 2014 10:30:15 -0700 Subject: Push precision to type objects --- .../connection_adapters/abstract_adapter.rb | 9 +++++++-- .../lib/active_record/connection_adapters/column.rb | 7 ++----- .../connection_adapters/postgresql_adapter.rb | 18 +++++++++++++++--- .../connection_adapters/type/date_time.rb | 4 ---- .../active_record/connection_adapters/type/numeric.rb | 4 ---- .../active_record/connection_adapters/type/value.rb | 7 +++---- 6 files changed, 27 insertions(+), 22 deletions(-) (limited to 'activerecord/lib/active_record/connection_adapters') diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index 875736350e..f3162419c7 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -391,11 +391,12 @@ module ActiveRecord m.register_type %r(int)i, Type::Integer.new m.register_type(%r(decimal)i) do |sql_type| scale = extract_scale(sql_type) + precision = extract_precision(sql_type) if scale == 0 - Type::Integer.new + Type::Integer.new(precision: precision) else - Type::Decimal.new(scale: scale) + Type::Decimal.new(precision: precision, scale: scale) end end end @@ -412,6 +413,10 @@ module ActiveRecord end end + def extract_precision(sql_type) # :nodoc: + $1.to_i if sql_type =~ /\((\d+)(,\d+)?\)/ + end + def translate_exception_class(e, sql) message = "#{e.class.name}: #{e.message}: #{sql}" @logger.error message if @logger diff --git a/activerecord/lib/active_record/connection_adapters/column.rb b/activerecord/lib/active_record/connection_adapters/column.rb index c110f2ab54..10ea25748d 100644 --- a/activerecord/lib/active_record/connection_adapters/column.rb +++ b/activerecord/lib/active_record/connection_adapters/column.rb @@ -13,12 +13,12 @@ module ActiveRecord ISO_DATETIME = /\A(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)(\.\d+)?\z/ end - attr_reader :name, :default, :cast_type, :limit, :null, :sql_type, :precision, :default_function + attr_reader :name, :default, :cast_type, :limit, :null, :sql_type, :default_function attr_accessor :primary, :coder alias :encoded? :coder - delegate :type, :scale, :klass, :text?, :number?, :binary?, :type_cast_for_write, to: :cast_type + delegate :type, :precision, :scale, :klass, :text?, :number?, :binary?, :type_cast_for_write, to: :cast_type # Instantiates a new column in the table. # @@ -35,7 +35,6 @@ module ActiveRecord @sql_type = sql_type @null = null @limit = extract_limit(sql_type) - @precision = extract_precision(sql_type) @default = extract_default(default) @default_function = nil @primary = nil @@ -68,8 +67,6 @@ module ActiveRecord end private - delegate :extract_precision, to: :cast_type - def extract_limit(sql_type) $1.to_i if sql_type =~ /\((.*)\)/ end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index f4a5cc11e2..5b7240b463 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -551,6 +551,8 @@ module ActiveRecord } end + OID_FOR_DECIMAL_TREATED_AS_INT = 23 # :nodoc: + def normalize_oid_type(ftype, fmod) # The type for the numeric depends on the width of the field, # so we'll do something special here. @@ -560,7 +562,7 @@ module ActiveRecord # places after decimal = fmod - 4 & 0xffff # places before decimal = (fmod - 4) >> 16 & 0xffff if ftype == 1700 && (fmod - 4 & 0xffff).zero? - 23 + OID_FOR_DECIMAL_TREATED_AS_INT else ftype end @@ -581,7 +583,6 @@ module ActiveRecord m.register_type 'bool', Type::Boolean.new m.register_type 'bit', OID::Bit.new m.alias_type 'varbit', 'bit' - m.register_type 'timestamp', OID::DateTime.new m.alias_type 'timestamptz', 'timestamp' m.register_type 'date', OID::Date.new m.register_type 'time', OID::Time.new @@ -609,9 +610,20 @@ module ActiveRecord m.alias_type 'lseg', 'varchar' m.alias_type 'box', 'varchar' + m.register_type 'timestamp' do |_, sql_type| + precision = extract_precision(sql_type) + OID::DateTime.new(precision: precision) + end + m.register_type 'numeric' do |_, sql_type| + precision = extract_precision(sql_type) scale = extract_scale(sql_type) - OID::Decimal.new(scale: scale) + OID::Decimal.new(precision: precision, scale: scale) + end + + m.register_type OID_FOR_DECIMAL_TREATED_AS_INT do |_, sql_type| + precision = extract_precision(sql_type) + OID::Integer.new(precision: precision) end load_additional_types(m) diff --git a/activerecord/lib/active_record/connection_adapters/type/date_time.rb b/activerecord/lib/active_record/connection_adapters/type/date_time.rb index 43203a4cd4..c34f4c5a53 100644 --- a/activerecord/lib/active_record/connection_adapters/type/date_time.rb +++ b/activerecord/lib/active_record/connection_adapters/type/date_time.rb @@ -8,10 +8,6 @@ module ActiveRecord :datetime end - def extract_precision(sql_type) - $1.to_i if sql_type =~ /\((\d+)\)/ - end - private def cast_value(string) diff --git a/activerecord/lib/active_record/connection_adapters/type/numeric.rb b/activerecord/lib/active_record/connection_adapters/type/numeric.rb index 15081daf8d..a3379831cb 100644 --- a/activerecord/lib/active_record/connection_adapters/type/numeric.rb +++ b/activerecord/lib/active_record/connection_adapters/type/numeric.rb @@ -14,10 +14,6 @@ module ActiveRecord else super end end - - def extract_precision(sql_type) - $1.to_i if sql_type =~ /\((\d+)(,\d+)?\)/ - end end end end diff --git a/activerecord/lib/active_record/connection_adapters/type/value.rb b/activerecord/lib/active_record/connection_adapters/type/value.rb index b37c3bad58..787b51dfa4 100644 --- a/activerecord/lib/active_record/connection_adapters/type/value.rb +++ b/activerecord/lib/active_record/connection_adapters/type/value.rb @@ -2,17 +2,16 @@ module ActiveRecord module ConnectionAdapters module Type class Value # :nodoc: - attr_reader :scale + attr_reader :precision, :scale def initialize(options = {}) - options.assert_valid_keys(:scale) + options.assert_valid_keys(:precision, :scale) + @precision = options[:precision] @scale = options[:scale] end def type; end - def extract_precision(sql_type); end - def type_cast(value) cast_value(value) unless value.nil? end -- cgit v1.2.3