aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2014-05-22 09:39:16 -0700
committerSean Griffin <sean@thoughtbot.com>2014-05-22 09:43:30 -0700
commit4826a4ab348e59c3ac1f6c31fd73f93eabb91a3b (patch)
tree053d88e831c9b6c95fecc29a32bd5f21c7b3b488 /activerecord/lib/active_record/connection_adapters
parent110d3d0c0bceddd05cab86c0463f0aa71df815cb (diff)
downloadrails-4826a4ab348e59c3ac1f6c31fd73f93eabb91a3b.tar.gz
rails-4826a4ab348e59c3ac1f6c31fd73f93eabb91a3b.tar.bz2
rails-4826a4ab348e59c3ac1f6c31fd73f93eabb91a3b.zip
Use the generic type map for all PG type registrations
We're going to want all of the benefits of the type map object for registrations, including block registration and real aliasing. Moves type name registrations to the adapter, and aliases the OIDs to the named types
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters')
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid.rb67
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb19
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb51
3 files changed, 62 insertions, 75 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
index e54c092bf6..2494e19f84 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
@@ -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
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb
index 27829ae1a3..28f7a4eafb 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb
@@ -13,7 +13,8 @@ module ActiveRecord
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 @@ module ActiveRecord
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 @@ module ActiveRecord
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
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index ed3e884455..29288d93a3 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -540,7 +540,7 @@ module ActiveRecord
def get_oid_type(oid, fmod, column_name)
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)) {
@@ -566,7 +566,54 @@ module ActiveRecord
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