diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-04-01 09:56:06 -0500 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-04-01 09:56:06 -0500 |
commit | fc0b98da0b83329474922a920a6070d370091228 (patch) | |
tree | 95e2accfedbc0109c921713ca2f19a5eee9d2be8 /activerecord/lib/active_record/connection_adapters | |
parent | f54dd28a34ad4204cb8af49fee2e20cb347bba16 (diff) | |
parent | 4d344bb4fdc0a57aff60c755dda0c5e3c6e08cdb (diff) | |
download | rails-fc0b98da0b83329474922a920a6070d370091228.tar.gz rails-fc0b98da0b83329474922a920a6070d370091228.tar.bz2 rails-fc0b98da0b83329474922a920a6070d370091228.zip |
Merge pull request #14513 from senny/pg/responsible_oid
PostgreSQL determine `Column#type` through corresponding OID. #7814
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql/column.rb | 65 | ||||
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql/oid.rb | 127 |
2 files changed, 91 insertions, 101 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/column.rb b/activerecord/lib/active_record/connection_adapters/postgresql/column.rb index 823189934d..2cbcd5fd50 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/column.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/column.rb @@ -151,70 +151,7 @@ module ActiveRecord # Maps PostgreSQL-specific data types to logical Rails types. def simplified_type(field_type) - case field_type - # Numeric and monetary types - when /^(?:real|double precision)$/ - :float - # Monetary types - when 'money' - :decimal - when 'hstore' - :hstore - when 'ltree' - :ltree - # Network address types - when 'inet' - :inet - when 'cidr' - :cidr - when 'macaddr' - :macaddr - # Character types - when /^(?:character varying|bpchar)(?:\(\d+\))?$/ - :string - when /^citext(?:\(\d+\))?$/ - :citext - # Binary data types - when 'bytea' - :binary - # Date/time types - when /^timestamp with(?:out)? time zone$/ - :datetime - when /^interval(?:|\(\d+\))$/ - :string - # Geometric types - when /^(?:point|line|lseg|box|"?path"?|polygon|circle)$/ - :string - # Bit strings - when /^bit(?: varying)?(?:\(\d+\))?$/ - :string - # XML type - when 'xml' - :xml - # tsvector type - when 'tsvector' - :tsvector - # Arrays - when /^\D+\[\]$/ - :string - # Object identifier types - when 'oid' - :integer - # UUID type - when 'uuid' - :uuid - # JSON type - when 'json' - :json - # Small and big integer types - when /^(?:small|big)int$/ - :integer - when /(num|date|tstz|ts|int4|int8)range$/ - field_type.to_sym - # Pass through all types that are not specific to PostgreSQL. - else - super - end + @oid_type.simplified_type(field_type) || super end end end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb index 5d32aaed50..57bdc3bb19 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb @@ -6,6 +6,7 @@ module ActiveRecord module OID class Type def type; end + def simplified_type(sql_type); type end def infinity(options = {}) ::Float::INFINITY * (options[:negative] ? -1 : 1) @@ -18,7 +19,9 @@ module ActiveRecord end end - class Text < Type + class String < Type + def type; :string end + def type_cast(value) return if value.nil? @@ -26,9 +29,23 @@ module ActiveRecord end end + class SpecializedString < OID::String + def type; @type end + + def initialize(type) + @type = type + end + end + + class Text < OID::String + def type; :text end + end + class Bit < Type + def type; :string end + def type_cast(value) - if String === value + if ::String === value ConnectionAdapters::PostgreSQLColumn.string_to_bit value else value @@ -37,6 +54,8 @@ module ActiveRecord end class Bytea < Type + def type; :binary end + def type_cast(value) return if value.nil? PGconn.unescape_bytea value @@ -44,9 +63,11 @@ module ActiveRecord end class Money < Type + def type; :decimal end + def type_cast(value) return if value.nil? - return value unless String === value + return value unless ::String === value # Because money output is formatted according to the locale, there are two # cases to consider (note the decimal separators): @@ -88,8 +109,10 @@ module ActiveRecord end class Point < Type + def type; :string end + def type_cast(value) - if String === value + if ::String === value ConnectionAdapters::PostgreSQLColumn.string_to_point value else value @@ -98,13 +121,15 @@ module ActiveRecord end class Array < Type + def type; @subtype.type end + attr_reader :subtype def initialize(subtype) @subtype = subtype end def type_cast(value) - if String === value + if ::String === value ConnectionAdapters::PostgreSQLColumn.string_to_array value, @subtype else value @@ -114,6 +139,8 @@ module ActiveRecord class Range < Type attr_reader :subtype + def simplified_type(sql_type); sql_type.to_sym end + def initialize(subtype) @subtype = subtype end @@ -160,6 +187,8 @@ This is not reliable and will be removed in the future. end class Integer < Type + def type; :integer end + def type_cast(value) return if value.nil? @@ -168,6 +197,8 @@ This is not reliable and will be removed in the future. end class Boolean < Type + def type; :boolean end + def type_cast(value) return if value.nil? @@ -177,6 +208,14 @@ This is not reliable and will be removed in the future. class Timestamp < Type def type; :timestamp; end + def simplified_type(sql_type) + case sql_type + when /^timestamp with(?:out)? time zone$/ + :datetime + else + :timestamp + end + end def type_cast(value) return if value.nil? @@ -188,7 +227,7 @@ This is not reliable and will be removed in the future. end class Date < Type - def type; :datetime; end + def type; :date; end def type_cast(value) return if value.nil? @@ -200,6 +239,8 @@ This is not reliable and will be removed in the future. end class Time < Type + def type; :time end + def type_cast(value) return if value.nil? @@ -210,6 +251,8 @@ This is not reliable and will be removed in the future. end class Float < Type + def type; :float end + def type_cast(value) return if value.nil? @@ -218,6 +261,8 @@ This is not reliable and will be removed in the future. end class Decimal < Type + def type; :decimal end + def type_cast(value) return if value.nil? @@ -230,12 +275,16 @@ This is not reliable and will be removed in the future. end class Enum < Type + def type; :enum end + def type_cast(value) value.to_s end end class Hstore < Type + def type; :hstore end + def type_cast_for_write(value) ConnectionAdapters::PostgreSQLColumn.hstore_to_string value end @@ -252,14 +301,20 @@ This is not reliable and will be removed in the future. end class Cidr < Type + def type; :cidr end def type_cast(value) return if value.nil? ConnectionAdapters::PostgreSQLColumn.string_to_cidr value end end + class Inet < Cidr + def type; :inet end + end class Json < Type + def type; :json end + def type_cast_for_write(value) ConnectionAdapters::PostgreSQLColumn.json_to_string value end @@ -321,7 +376,7 @@ This is not reliable and will be removed in the future. } # Register an OID type named +name+ with a typecasting object in - # +type+. +name+ should correspond to the `typname` column in + # +type+. +name+ should correspond to the `typname` column in # the `pg_type` table. def self.register_type(name, type) NAMES[name] = type @@ -338,48 +393,46 @@ This is not reliable and will be removed in the future. end register_type 'int2', OID::Integer.new - alias_type 'int4', 'int2' - alias_type 'int8', 'int2' - alias_type 'oid', 'int2' - + alias_type 'int4', 'int2' + alias_type 'int8', 'int2' + alias_type 'oid', 'int2' register_type 'numeric', OID::Decimal.new + register_type 'float4', OID::Float.new + alias_type 'float8', 'float4' register_type 'text', OID::Text.new - alias_type 'varchar', 'text' - alias_type 'char', 'text' - alias_type 'bpchar', 'text' - alias_type 'xml', 'text' - - # FIXME: why are we keeping these types as strings? - alias_type 'tsvector', 'text' - alias_type 'interval', 'text' - alias_type 'macaddr', 'text' - alias_type 'uuid', 'text' - - register_type 'money', OID::Money.new - register_type 'bytea', OID::Bytea.new + register_type 'varchar', OID::String.new + alias_type 'char', 'varchar' + alias_type 'bpchar', 'varchar' register_type 'bool', OID::Boolean.new register_type 'bit', OID::Bit.new - register_type 'varbit', OID::Bit.new - - register_type 'float4', OID::Float.new - alias_type 'float8', 'float4' - + alias_type 'varbit', 'bit' register_type 'timestamp', OID::Timestamp.new - register_type 'timestamptz', OID::Timestamp.new + alias_type 'timestamptz', 'timestamp' register_type 'date', OID::Date.new register_type 'time', OID::Time.new - register_type 'path', OID::Text.new + register_type 'money', OID::Money.new + register_type 'bytea', OID::Bytea.new register_type 'point', OID::Point.new - register_type 'polygon', OID::Text.new - register_type 'circle', OID::Text.new register_type 'hstore', OID::Hstore.new register_type 'json', OID::Json.new - register_type 'citext', OID::Text.new - register_type 'ltree', OID::Text.new - register_type 'cidr', OID::Cidr.new - alias_type 'inet', 'cidr' + register_type 'inet', OID::Inet.new + register_type 'xml', SpecializedString.new(:xml) + register_type 'tsvector', SpecializedString.new(:tsvector) + register_type 'macaddr', SpecializedString.new(:macaddr) + register_type 'uuid', SpecializedString.new(:uuid) + register_type 'citext', SpecializedString.new(:citext) + register_type 'ltree', SpecializedString.new(:ltree) + + # FIXME: why are we keeping these types as strings? + alias_type 'interval', 'varchar' + alias_type 'path', 'varchar' + alias_type 'line', 'varchar' + alias_type 'polygon', 'varchar' + alias_type 'circle', 'varchar' + alias_type 'lseg', 'varchar' + alias_type 'box', 'varchar' end end end |