Module: Foreigner::ConnectionAdapters::PostgreSQLAdapter

Includes:
Sql2003
Defined in:
lib/foreigner/connection_adapters/postgresql_adapter.rb

Constant Summary collapse

DEPENDENCY_CODE_ACTIONS =
{'c' => 'CASCADE', 'n' => 'SET NULL', 'r' => 'RESTRICT', 'd' => 'SET DEFAULT'}

Instance Method Summary collapse

Methods included from Sql2003

#add_foreign_key, #add_foreign_key_sql, #drop_table, #foreign_key_exists?, #proper_table_name, #quote_proper_table_name, #remove_foreign_key, #remove_foreign_key_sql, #supports_foreign_keys?

Instance Method Details

#foreign_keys(table_name) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/foreigner/connection_adapters/postgresql_adapter.rb', line 8

def foreign_keys(table_name)
  fk_info = select_all %{
    SELECT t2.relname AS to_table
         , a1.attname AS column
         , a2.attname AS primary_key
         , c.conname AS name
         , c.confdeltype AS dependency
         , c.confupdtype AS update_dependency
         , c.condeferrable AS deferrable
         , c.condeferred AS deferred
      #{", c.convalidated AS valid" if postgresql_version >= 90100}
    FROM pg_constraint c
    JOIN pg_class t1 ON c.conrelid = t1.oid
    JOIN pg_class t2 ON c.confrelid = t2.oid
    JOIN pg_attribute a1 ON a1.attnum = c.conkey[1] AND a1.attrelid = t1.oid
    JOIN pg_attribute a2 ON a2.attnum = c.confkey[1] AND a2.attrelid = t2.oid
    JOIN pg_namespace t3 ON c.connamespace = t3.oid
    WHERE c.contype = 'f'
      AND t1.relname = '#{table_name}'
      AND t3.nspname = ANY (current_schemas(false))
    ORDER BY c.conname
  }

  fk_info.map do |row|
    options = {column: row['column'], name: row['name'], primary_key: row['primary_key']}

    options[:dependent] = case row['dependency']
      # NO ACTION is the default
      # SET DEFAULT is handled below, since it is postgres-specific
      when 'c' then :delete
      when 'n' then :nullify
      when 'r' then :restrict
    end

    extras = []
    extras << "ON DELETE SET DEFAULT"      if row['dependency'] == 'd'
    if update_action = DEPENDENCY_CODE_ACTIONS[row['update_dependency']]
      extras << "ON UPDATE #{update_action}"
    end
    extras << 'DEFERRABLE'                 if row['deferrable'] == 't'
    extras << 'INITIALLY DEFERRED'         if row['deferred'] == 't'
    extras << 'NOT VALID'                  if row['valid'] == 'f'
    options[:options] = extras.join(" ")

    ForeignKeyDefinition.new(table_name, row['to_table'], options)
  end
end