提交 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
module ConnectionAdapters
module PostgreSQL
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
......
......@@ -13,7 +13,8 @@ def initialize(store)
end
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' }
enums, nodes = nodes.partition { |row| row['typtype'] == 'e' }
domains, nodes = nodes.partition { |row| row['typtype'] == 'd' }
......@@ -30,7 +31,7 @@ def run(records)
private
def register_mapped_type(row)
register row['oid'], OID::NAMES[row['typname']]
alias_type row['oid'], row['typname']
end
def register_enum_type(row)
......@@ -64,12 +65,18 @@ def register_composite_type(row)
end
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?
return if @store.key?(oid)
def alias_type(oid, target)
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
......
......@@ -540,7 +540,7 @@ def translate_exception(exception, message)
def get_oid_type(oid, fmod, column_name, sql_type = '')
if !type_map.key?(oid)
initialize_type_map(type_map, [oid])
load_additional_types(type_map, [oid])
end
type_map.fetch(normalize_oid_type(oid, fmod), sql_type) {
......@@ -566,7 +566,54 @@ def normalize_oid_type(ftype, fmod)
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?
query = <<-SQL
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)
def setup
super
@registration = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID
@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")
@connection.type_map.register_type "full_address", FullAddressType.new
end
def test_column
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册