module ActiveRecord module ConnectionAdapters module PostgreSQL module OID # :nodoc: # This class uses the data from PostgreSQL pg_type table to build # the OID -> Type mapping. # - OID is and integer representing the type. # - Type is an OID::Type object. # This class has side effects on the +store+ passed during initialization. class TypeMapInitializer # :nodoc: def initialize(store) @store = store end def run(records) 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' } arrays, nodes = nodes.partition { |row| row['typinput'] == 'array_in' } composites, nodes = nodes.partition { |row| row['typelem'] != '0' } mapped.each { |row| register_mapped_type(row) } enums.each { |row| register_enum_type(row) } domains.each { |row| register_domain_type(row) } arrays.each { |row| register_array_type(row) } ranges.each { |row| register_range_type(row) } composites.each { |row| register_composite_type(row) } end private def register_mapped_type(row) alias_type row['oid'], row['typname'] end def register_enum_type(row) register row['oid'], OID::Enum.new end def register_array_type(row) if subtype = @store.lookup(row['typelem'].to_i) register row['oid'], OID::Array.new(subtype, row['typdelim']) end end def register_range_type(row) if subtype = @store.lookup(row['rngsubtype'].to_i) register row['oid'], OID::Range.new(subtype, row['typname'].to_sym) end end def register_domain_type(row) if base_type = @store.lookup(row["typbasetype"].to_i) register row['oid'], base_type else warn "unknown base type (OID: #{row["typbasetype"]}) for domain #{row["typname"]}." end end def register_composite_type(row) if subtype = @store.lookup(row['typelem'].to_i) register row['oid'], OID::Vector.new(row['typdelim'], subtype) end end def register(oid, oid_type) oid = assert_valid_registration(oid, oid_type) @store.register_type(oid, oid_type) end def alias_type(oid, target) oid = assert_valid_registration(oid, target) @store.alias_type(oid, target) end 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