Merge remote-tracking branch 'jfirebaugh/legacy-params'
[rails.git] / config / initializers / postgresql_adapter.rb
1 if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
2   module ActiveRecord
3     module ConnectionAdapters
4       class PostgreSQLAdapter
5         def supports_disable_referential_integrity?() #:nodoc:
6           version = query("SHOW server_version")[0][0].split('.')
7           (version[0].to_i >= 9 || (version[0].to_i == 8 && version[1].to_i >= 1)) ? true : false
8         rescue
9           return false
10         end
11
12         def pk_and_sequence_for(table)
13           # First try looking for a sequence with a dependency on the
14           # given table's primary key.
15           result = query(<<-end_sql, 'PK and serial sequence')[0]
16             SELECT attr.attname, seq.relname
17             FROM pg_class      seq,
18                  pg_attribute  attr,
19                  pg_depend     dep,
20                  pg_namespace  name,
21                  pg_constraint cons
22             WHERE seq.oid           = dep.objid
23               AND seq.relkind       = 'S'
24               AND attr.attrelid     = dep.refobjid
25               AND attr.attnum       = dep.refobjsubid
26               AND attr.attrelid     = cons.conrelid
27               AND attr.attnum       = cons.conkey[1]
28               AND cons.contype      = 'p'
29               AND dep.classid       = '"pg_class"'::regclass
30               AND dep.refclassid    = '"pg_class"'::regclass
31               AND dep.refobjid      = '#{quote_table_name(table)}'::regclass
32           end_sql
33   
34           if result.nil? or result.empty?
35             # If that fails, try parsing the primary key's default value.
36             # Support the 7.x and 8.0 nextval('foo'::text) as well as
37             # the 8.1+ nextval('foo'::regclass).
38             result = query(<<-end_sql, 'PK and custom sequence')[0]
39               SELECT attr.attname,
40                 CASE
41                   WHEN split_part(def.adsrc, '''', 2) ~ '.' THEN
42                     substr(split_part(def.adsrc, '''', 2),
43                            strpos(split_part(def.adsrc, '''', 2), '.')+1)
44                   ELSE split_part(def.adsrc, '''', 2)
45                 END
46               FROM pg_class       t
47               JOIN pg_attribute   attr ON (t.oid = attrelid)
48               JOIN pg_attrdef     def  ON (adrelid = attrelid AND adnum = attnum)
49               JOIN pg_constraint  cons ON (conrelid = adrelid AND adnum = conkey[1])
50               WHERE t.oid = '#{quote_table_name(table)}'::regclass
51                 AND cons.contype = 'p'
52                 AND def.adsrc ~* 'nextval'
53             end_sql
54           end
55   
56           # [primary_key, sequence]
57           [result.first, result.last]
58         rescue
59           nil
60         end
61
62         def initialize_type_map_with_enums
63           OID.alias_type "format_enum", "text"
64           OID.alias_type "gpx_visibility_enum", "text"
65           OID.alias_type "note_status_enum", "text"
66           OID.alias_type "note_event_enum", "text"
67           OID.alias_type "nwr_enum", "text"
68           OID.alias_type "user_role_enum", "text"
69           OID.alias_type "user_status_enum", "text"
70
71           initialize_type_map_without_enums
72         end
73
74         alias_method_chain :initialize_type_map, :enums
75       end
76
77       class PostgreSQLColumn
78         def simplified_type_with_enum(field_type)
79           case field_type
80           when /_enum$/
81             :string
82           else
83             simplified_type_without_enum(field_type)
84           end
85         end
86
87         alias_method_chain :simplified_type, :enum
88       end
89     end
90   end
91 end