From 57cc778fc851c606af4eb5f1dbc979d114637490 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Thu, 22 May 2014 10:03:26 -0700 Subject: Push scale to type objects Ideally types will be usable without having to specify a sql type string, so we should keep the information related to parsing them on the adapter or another object. --- .../active_record/connection_adapters/abstract_adapter.rb | 13 +++++++++++-- .../lib/active_record/connection_adapters/column.rb | 7 +++---- .../connection_adapters/postgresql/oid/money.rb | 2 +- .../active_record/connection_adapters/postgresql_adapter.rb | 6 +++++- activerecord/lib/active_record/connection_adapters/type.rb | 8 -------- .../lib/active_record/connection_adapters/type/decimal.rb | 2 -- .../lib/active_record/connection_adapters/type/value.rb | 9 +++++++-- 7 files changed, 27 insertions(+), 20 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 0c55dbb037..875736350e 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -390,10 +390,12 @@ module ActiveRecord m.alias_type %r(double)i, 'float' m.register_type %r(int)i, Type::Integer.new m.register_type(%r(decimal)i) do |sql_type| - if Type.extract_scale(sql_type) == 0 + scale = extract_scale(sql_type) + + if scale == 0 Type::Integer.new else - Type::Decimal.new + Type::Decimal.new(scale: scale) end end end @@ -403,6 +405,13 @@ module ActiveRecord initialize_type_map(type_map) end + def extract_scale(sql_type) # :nodoc: + case sql_type + when /\((\d+)\)/ then 0 + when /\((\d+)(,(\d+))\)/ then $3.to_i + end + 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 522fa57822..c110f2ab54 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, :scale, :default_function + attr_reader :name, :default, :cast_type, :limit, :null, :sql_type, :precision, :default_function attr_accessor :primary, :coder alias :encoded? :coder - delegate :type, :klass, :text?, :number?, :binary?, :type_cast_for_write, to: :cast_type + delegate :type, :scale, :klass, :text?, :number?, :binary?, :type_cast_for_write, to: :cast_type # Instantiates a new column in the table. # @@ -36,7 +36,6 @@ module ActiveRecord @null = null @limit = extract_limit(sql_type) @precision = extract_precision(sql_type) - @scale = extract_scale(sql_type) @default = extract_default(default) @default_function = nil @primary = nil @@ -69,7 +68,7 @@ module ActiveRecord end private - delegate :extract_scale, :extract_precision, to: :cast_type + delegate :extract_precision, to: :cast_type def extract_limit(sql_type) $1.to_i if sql_type =~ /\((.*)\)/ diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/money.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/money.rb index 74e8f30457..697dceb7c2 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/money.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/money.rb @@ -7,7 +7,7 @@ module ActiveRecord class_attribute :precision - def extract_scale(sql_type) + def scale 2 end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index b0cbccb7ba..f4a5cc11e2 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -571,7 +571,6 @@ module ActiveRecord m.alias_type 'int4', 'int2' m.alias_type 'int8', 'int2' m.alias_type 'oid', 'int2' - m.register_type 'numeric', OID::Decimal.new m.register_type 'float4', OID::Float.new m.alias_type 'float8', 'float4' m.register_type 'text', Type::Text.new @@ -610,6 +609,11 @@ module ActiveRecord m.alias_type 'lseg', 'varchar' m.alias_type 'box', 'varchar' + m.register_type 'numeric' do |_, sql_type| + scale = extract_scale(sql_type) + OID::Decimal.new(scale: scale) + end + load_additional_types(m) end diff --git a/activerecord/lib/active_record/connection_adapters/type.rb b/activerecord/lib/active_record/connection_adapters/type.rb index 9103ae85c0..395a4160a8 100644 --- a/activerecord/lib/active_record/connection_adapters/type.rb +++ b/activerecord/lib/active_record/connection_adapters/type.rb @@ -19,14 +19,6 @@ require 'active_record/connection_adapters/type/hash_lookup_type_map' module ActiveRecord module ConnectionAdapters module Type # :nodoc: - class << self - def extract_scale(sql_type) - case sql_type - when /\((\d+)\)/ then 0 - when /\((\d+)(,(\d+))\)/ then $3.to_i - end - end - end end end end diff --git a/activerecord/lib/active_record/connection_adapters/type/decimal.rb b/activerecord/lib/active_record/connection_adapters/type/decimal.rb index a8cd1cf5b5..ac5af4b963 100644 --- a/activerecord/lib/active_record/connection_adapters/type/decimal.rb +++ b/activerecord/lib/active_record/connection_adapters/type/decimal.rb @@ -4,8 +4,6 @@ module ActiveRecord class Decimal < Value # :nodoc: include Numeric - delegate :extract_scale, to: Type - def type :decimal end diff --git a/activerecord/lib/active_record/connection_adapters/type/value.rb b/activerecord/lib/active_record/connection_adapters/type/value.rb index 6687c9a2a4..b37c3bad58 100644 --- a/activerecord/lib/active_record/connection_adapters/type/value.rb +++ b/activerecord/lib/active_record/connection_adapters/type/value.rb @@ -2,9 +2,14 @@ module ActiveRecord module ConnectionAdapters module Type class Value # :nodoc: - def type; end + attr_reader :scale + + def initialize(options = {}) + options.assert_valid_keys(:scale) + @scale = options[:scale] + end - def extract_scale(sql_type); end + def type; end def extract_precision(sql_type); end -- cgit v1.2.3