提交 b343e310 编写于 作者: R Rafael Mendonça França

Merge pull request #15249 from sgrif/sg-register-types-in-adapter

Use the generic type map for all PG type registrations
...@@ -27,73 +27,6 @@ module ActiveRecord ...@@ -27,73 +27,6 @@ module ActiveRecord
module ConnectionAdapters module ConnectionAdapters
module PostgreSQL module PostgreSQL
module OID # :nodoc: module OID # :nodoc:
# When the PG adapter connects, the pg_type table is queried. The
# key of this hash maps to the `typname` column from the table.
# type_map is then dynamically built with oids as the key and type
# objects as values.
NAMES = Hash.new { |h,k| # :nodoc:
h[k] = Type::Value.new
}
# Register an OID type named +name+ with a typecasting object in
# +type+. +name+ should correspond to the `typname` column in
# the `pg_type` table.
def self.register_type(name, type)
NAMES[name] = type
end
# Alias the +old+ type to the +new+ type.
def self.alias_type(new, old)
NAMES[new] = NAMES[old]
end
# Is +name+ a registered type?
def self.registered_type?(name)
NAMES.key? name
end
register_type 'int2', OID::Integer.new
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', Type::Text.new
register_type 'varchar', Type::String.new
alias_type 'char', 'varchar'
alias_type 'name', 'varchar'
alias_type 'bpchar', 'varchar'
register_type 'bool', Type::Boolean.new
register_type 'bit', OID::Bit.new
alias_type 'varbit', 'bit'
register_type 'timestamp', OID::DateTime.new
alias_type 'timestamptz', 'timestamp'
register_type 'date', OID::Date.new
register_type 'time', OID::Time.new
register_type 'money', OID::Money.new
register_type 'bytea', OID::Bytea.new
register_type 'point', OID::Point.new
register_type 'hstore', OID::Hstore.new
register_type 'json', OID::Json.new
register_type 'cidr', OID::Cidr.new
register_type 'inet', OID::Inet.new
register_type 'uuid', OID::Uuid.new
register_type 'xml', SpecializedString.new(:xml)
register_type 'tsvector', SpecializedString.new(:tsvector)
register_type 'macaddr', SpecializedString.new(:macaddr)
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 end
end end
......
...@@ -13,7 +13,8 @@ def initialize(store) ...@@ -13,7 +13,8 @@ def initialize(store)
end end
def run(records) def run(records)
mapped, nodes = records.partition { |row| OID.registered_type? row['typname'] } nodes = records.reject { |row| @store.key? row['oid'].to_i }
mapped, nodes = nodes.partition { |row| @store.key? row['typname'] }
ranges, nodes = nodes.partition { |row| row['typtype'] == 'r' } ranges, nodes = nodes.partition { |row| row['typtype'] == 'r' }
enums, nodes = nodes.partition { |row| row['typtype'] == 'e' } enums, nodes = nodes.partition { |row| row['typtype'] == 'e' }
domains, nodes = nodes.partition { |row| row['typtype'] == 'd' } domains, nodes = nodes.partition { |row| row['typtype'] == 'd' }
...@@ -30,7 +31,7 @@ def run(records) ...@@ -30,7 +31,7 @@ def run(records)
private private
def register_mapped_type(row) def register_mapped_type(row)
register row['oid'], OID::NAMES[row['typname']] alias_type row['oid'], row['typname']
end end
def register_enum_type(row) def register_enum_type(row)
...@@ -64,12 +65,18 @@ def register_composite_type(row) ...@@ -64,12 +65,18 @@ def register_composite_type(row)
end end
def register(oid, oid_type) def register(oid, oid_type)
oid = oid.to_i oid = assert_valid_registration(oid, oid_type)
@store.register_type(oid, oid_type)
end
raise ArgumentError, "can't register nil type for OID #{oid}" if oid_type.nil? def alias_type(oid, target)
return if @store.key?(oid) oid = assert_valid_registration(oid, target)
@store.alias_type(oid, target)
end
@store.register_type(oid, oid_type) def assert_valid_registration(oid, oid_type)
raise ArgumentError, "can't register nil type for OID #{oid}" if oid_type.nil?
oid.to_i
end end
end end
end end
......
...@@ -540,7 +540,7 @@ def translate_exception(exception, message) ...@@ -540,7 +540,7 @@ def translate_exception(exception, message)
def get_oid_type(oid, fmod, column_name, sql_type = '') def get_oid_type(oid, fmod, column_name, sql_type = '')
if !type_map.key?(oid) if !type_map.key?(oid)
initialize_type_map(type_map, [oid]) load_additional_types(type_map, [oid])
end end
type_map.fetch(normalize_oid_type(oid, fmod), sql_type) { type_map.fetch(normalize_oid_type(oid, fmod), sql_type) {
...@@ -566,7 +566,54 @@ def normalize_oid_type(ftype, fmod) ...@@ -566,7 +566,54 @@ def normalize_oid_type(ftype, fmod)
end end
end end
def initialize_type_map(type_map, oids = nil) def initialize_type_map(m)
m.register_type 'int2', OID::Integer.new
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
m.register_type 'varchar', Type::String.new
m.alias_type 'char', 'varchar'
m.alias_type 'name', 'varchar'
m.alias_type 'bpchar', 'varchar'
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
m.register_type 'money', OID::Money.new
m.register_type 'bytea', OID::Bytea.new
m.register_type 'point', OID::Point.new
m.register_type 'hstore', OID::Hstore.new
m.register_type 'json', OID::Json.new
m.register_type 'cidr', OID::Cidr.new
m.register_type 'inet', OID::Inet.new
m.register_type 'uuid', OID::Uuid.new
m.register_type 'xml', OID::SpecializedString.new(:xml)
m.register_type 'tsvector', OID::SpecializedString.new(:tsvector)
m.register_type 'macaddr', OID::SpecializedString.new(:macaddr)
m.register_type 'citext', OID::SpecializedString.new(:citext)
m.register_type 'ltree', OID::SpecializedString.new(:ltree)
# FIXME: why are we keeping these types as strings?
m.alias_type 'interval', 'varchar'
m.alias_type 'path', 'varchar'
m.alias_type 'line', 'varchar'
m.alias_type 'polygon', 'varchar'
m.alias_type 'circle', 'varchar'
m.alias_type 'lseg', 'varchar'
m.alias_type 'box', 'varchar'
load_additional_types(m)
end
def load_additional_types(type_map, oids = nil)
if supports_ranges? if supports_ranges?
query = <<-SQL query = <<-SQL
SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
......
...@@ -102,15 +102,7 @@ def type_cast_for_write(value) ...@@ -102,15 +102,7 @@ def type_cast_for_write(value)
def setup def setup
super super
@registration = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID @connection.type_map.register_type "full_address", FullAddressType.new
@registration.register_type "full_address", FullAddressType.new
end
def teardown
super
# there is currently no clean way to unregister a OID::Type
@registration::NAMES.delete("full_address")
end end
def test_column def test_column
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册