matthuhiggins-foreigner 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/foreigner.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require 'foreigner/connection_adapters/abstract/schema_statements'
2
2
  require 'foreigner/connection_adapters/abstract/schema_definitions'
3
- require 'foreigner/connection_adapters/mysql_adapter'
4
3
  require 'foreigner/schema_dumper'
5
4
 
6
5
  module ActiveRecord
@@ -8,10 +7,6 @@ module ActiveRecord
8
7
  AbstractAdapter.class_eval do
9
8
  include Foreigner::AdapterMethods
10
9
  end
11
-
12
- MysqlAdapter.class_eval do
13
- include Foreigner::MysqlAdapter
14
- end
15
10
 
16
11
  TableDefinition.class_eval do
17
12
  include Foreigner::TableDefinition
@@ -25,4 +20,10 @@ module ActiveRecord
25
20
  SchemaDumper.class_eval do
26
21
  include Foreigner::SchemaDumper
27
22
  end
23
+
24
+ Base.class_eval do
25
+ if ['MySQL', 'PostgreSQL'].include? connection.adapter_name
26
+ require "foreigner/connection_adapters/#{connection.adapter_name.downcase}_adapter"
27
+ end
28
+ end
28
29
  end
@@ -1,84 +1,46 @@
1
- module Foreigner
2
- module MysqlAdapter
3
- def supports_foreign_keys?
4
- true
5
- end
6
-
7
- def add_foreign_key(from_table, to_table, options = {})
8
- column = options[:column] || "#{to_table.to_s.singularize}_id"
9
- foreign_key_name = foreign_key_name(from_table, column, options)
1
+ require 'foreigner/connection_adapters/sql_2003'
10
2
 
11
- sql =
12
- "ALTER TABLE #{quote_table_name(from_table)} " +
13
- "ADD CONSTRAINT #{quote_column_name(foreign_key_name)} " +
14
- foreign_key_definition(to_table, options)
3
+ module Foreigner
4
+ module ConnectionAdapters
5
+ module MysqlAdapter
6
+ include Foreigner::ConnectionAdapters::Sql2003
15
7
 
16
- execute(sql)
17
- end
18
-
19
- def foreign_key_definition(to_table, options = {})
20
- column = options[:column] || "#{to_table.to_s.singularize}_id"
21
- dependency = dependency_sql(options[:dependent])
22
-
23
- sql = "FOREIGN KEY (#{quote_column_name(column)}) REFERENCES #{quote_table_name(to_table)}(id)"
24
- sql << " #{dependency}" unless dependency.blank?
25
- sql
26
- end
27
-
28
- def remove_foreign_key(table, options)
29
- if Hash === options
30
- foreign_key_name = foreign_key_name(table, options[:column], options)
31
- else
32
- foreign_key_name = foreign_key_name(table, "#{options.to_s.singularize}_id")
33
- end
34
-
35
- execute "ALTER TABLE #{quote_table_name(table)} DROP FOREIGN KEY #{quote_column_name(foreign_key_name)}"
36
- end
37
-
38
- def foreign_keys(table_name)
39
- foreign_keys = []
40
- fk_info = select_all %{
41
- SELECT fk.referenced_table_name as 'to_table'
42
- ,fk.column_name as 'column'
43
- ,fk.constraint_name as 'name'
44
- FROM information_schema.key_column_usage fk
45
- WHERE fk.referenced_column_name is not null
46
- AND fk.table_schema = '#{@config[:database]}'
47
- AND fk.table_name = '#{table_name}'
48
- }
49
-
50
- create_table_info = select_one("SHOW CREATE TABLE #{quote_table_name(table_name)}")["Create Table"]
51
-
52
- fk_info.each do |row|
53
- options = {:column => row['column'], :name => row['name']}
54
- if create_table_info =~ /CONSTRAINT #{quote_column_name(row['name'])} FOREIGN KEY .* REFERENCES .* ON DELETE (CASCADE|SET NULL)/
55
- if $1 == 'CASCADE'
56
- options[:dependent] = :delete
57
- elsif $1 == 'SET NULL'
58
- options[:dependent] = :nullify
8
+ def foreign_keys(table_name)
9
+ foreign_keys = []
10
+ fk_info = select_all %{
11
+ SELECT fk.referenced_table_name as 'to_table'
12
+ ,fk.column_name as 'column'
13
+ ,fk.constraint_name as 'name'
14
+ FROM information_schema.key_column_usage fk
15
+ WHERE fk.referenced_column_name is not null
16
+ AND fk.table_schema = '#{@config[:database]}'
17
+ AND fk.table_name = '#{table_name}'
18
+ }
19
+
20
+ create_table_info = select_one("SHOW CREATE TABLE #{quote_table_name(table_name)}")["Create Table"]
21
+
22
+ fk_info.each do |row|
23
+ options = {:column => row['column'], :name => row['name']}
24
+ if create_table_info =~ /CONSTRAINT #{quote_column_name(row['name'])} FOREIGN KEY .* REFERENCES .* ON DELETE (CASCADE|SET NULL)/
25
+ if $1 == 'CASCADE'
26
+ options[:dependent] = :delete
27
+ elsif $1 == 'SET NULL'
28
+ options[:dependent] = :nullify
29
+ end
59
30
  end
31
+ foreign_keys << ForeignKeyDefinition.new(table_name, row['to_table'], options)
60
32
  end
61
- foreign_keys << ForeignKeyDefinition.new(table_name, row['to_table'], options)
62
- end
63
33
 
64
- foreign_keys
65
- end
66
-
67
- private
68
- def foreign_key_name(table, column, options = {})
69
- if options[:name]
70
- options[:name]
71
- else
72
- "#{table}_#{column}_fk"
73
- end
34
+ foreign_keys
74
35
  end
36
+ end
37
+ end
38
+ end
75
39
 
76
- def dependency_sql(dependency)
77
- case dependency
78
- when :nullify then "ON DELETE SET NULL"
79
- when :delete then "ON DELETE CASCADE"
80
- else ""
81
- end
82
- end
40
+ module ActiveRecord
41
+ module ConnectionAdapters
42
+ MysqlAdapter.class_eval do
43
+ include Foreigner::ConnectionAdapters::MysqlAdapter
44
+ end
83
45
  end
84
46
  end
@@ -0,0 +1,54 @@
1
+ require 'foreigner/connection_adapters/sql_2003'
2
+
3
+ module Foreigner
4
+ module ConnectionAdapters
5
+ module PostgreSQLAdapter
6
+ include Foreigner::ConnectionAdapters::Sql2003
7
+
8
+ def foreign_keys(table_name)
9
+ foreign_keys = []
10
+
11
+ fk_info = select_all %{
12
+ select tc.constraint_name as name
13
+ ,ccu.table_name as to_table
14
+ ,kcu.column_name as column
15
+ ,rc.delete_rule as dependency
16
+ from information_schema.table_constraints tc
17
+ join information_schema.key_column_usage kcu
18
+ on tc.constraint_catalog = kcu.constraint_catalog
19
+ and tc.constraint_schema = kcu.constraint_schema
20
+ and tc.constraint_name = kcu.constraint_name
21
+ join information_schema.referential_constraints rc
22
+ on tc.constraint_catalog = rc.constraint_catalog
23
+ and tc.constraint_schema = rc.constraint_schema
24
+ and tc.constraint_name = rc.constraint_name
25
+ join information_schema.constraint_column_usage ccu
26
+ on tc.constraint_catalog = ccu.constraint_catalog
27
+ and tc.constraint_schema = ccu.constraint_schema
28
+ and tc.constraint_name = ccu.constraint_name
29
+ where tc.constraint_type = 'FOREIGN KEY'
30
+ and tc.constraint_catalog = '#{@config[:database]}'
31
+ and tc.table_name = '#{table_name}'
32
+ }
33
+
34
+ fk_info.inject([]) do |foreign_keys, row|
35
+ options = {:column => row['column'], :name => row['name']}
36
+ if row['dependency'] == 'CASCADE'
37
+ options[:dependent] = :delete
38
+ elsif row['dependency'] == 'SET NULL'
39
+ options[:dependent] = :nullify
40
+ end
41
+ foreign_keys << ForeignKeyDefinition.new(table_name, row['to_table'], options)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ module ActiveRecord
49
+ module ConnectionAdapters
50
+ PostgreSQLAdapter.class_eval do
51
+ include Foreigner::ConnectionAdapters::PostgreSQLAdapter
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,57 @@
1
+ module Foreigner
2
+ module ConnectionAdapters
3
+ module Sql2003
4
+ def supports_foreign_keys?
5
+ true
6
+ end
7
+
8
+ def add_foreign_key(from_table, to_table, options = {})
9
+ column = options[:column] || "#{to_table.to_s.singularize}_id"
10
+ foreign_key_name = foreign_key_name(from_table, column, options)
11
+
12
+ sql =
13
+ "ALTER TABLE #{quote_table_name(from_table)} " +
14
+ "ADD CONSTRAINT #{quote_column_name(foreign_key_name)} " +
15
+ foreign_key_definition(to_table, options)
16
+
17
+ execute(sql)
18
+ end
19
+
20
+ def foreign_key_definition(to_table, options = {})
21
+ column = options[:column] || "#{to_table.to_s.singularize}_id"
22
+ dependency = dependency_sql(options[:dependent])
23
+
24
+ sql = "FOREIGN KEY (#{quote_column_name(column)}) REFERENCES #{quote_table_name(to_table)}(id)"
25
+ sql << " #{dependency}" unless dependency.blank?
26
+ sql
27
+ end
28
+
29
+ def remove_foreign_key(table, options)
30
+ if Hash === options
31
+ foreign_key_name = foreign_key_name(table, options[:column], options)
32
+ else
33
+ foreign_key_name = foreign_key_name(table, "#{options.to_s.singularize}_id")
34
+ end
35
+
36
+ execute "ALTER TABLE #{quote_table_name(table)} DROP FOREIGN KEY #{quote_column_name(foreign_key_name)}"
37
+ end
38
+
39
+ private
40
+ def foreign_key_name(table, column, options = {})
41
+ if options[:name]
42
+ options[:name]
43
+ else
44
+ "#{table}_#{column}_fk"
45
+ end
46
+ end
47
+
48
+ def dependency_sql(dependency)
49
+ case dependency
50
+ when :nullify then "ON DELETE SET NULL"
51
+ when :delete then "ON DELETE CASCADE"
52
+ else ""
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
data/test/helper.rb CHANGED
@@ -5,5 +5,4 @@ require 'active_support/test_case'
5
5
  require 'active_record'
6
6
  require 'active_record/test_case'
7
7
  require 'active_record/connection_adapters/mysql_adapter'
8
- $:.unshift File.dirname(__FILE__) + '/../lib/'
9
8
  require 'foreigner'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: matthuhiggins-foreigner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Higgins
@@ -29,14 +29,15 @@ files:
29
29
  - lib/foreigner
30
30
  - lib/foreigner/schema_dumper.rb
31
31
  - lib/foreigner/connection_adapters
32
+ - lib/foreigner/connection_adapters/sql_2003.rb
32
33
  - lib/foreigner/connection_adapters/mysql_adapter.rb
34
+ - lib/foreigner/connection_adapters/postgresql_adapter.rb
33
35
  - lib/foreigner/connection_adapters/abstract/schema_definitions.rb
34
36
  - lib/foreigner/connection_adapters/abstract/schema_statements.rb
35
37
  - test/helper.rb
36
38
  - test/mysql_adapter_test.rb
37
39
  has_rdoc: false
38
40
  homepage: http://github.com/matthuhiggins/foreigner/tree/master
39
- licenses:
40
41
  post_install_message:
41
42
  rdoc_options:
42
43
  - --line-numbers
@@ -59,7 +60,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
59
60
  requirements: []
60
61
 
61
62
  rubyforge_project: foreigner
62
- rubygems_version: 1.3.5
63
+ rubygems_version: 1.2.0
63
64
  signing_key:
64
65
  specification_version: 1
65
66
  summary: Foreign keys for Rails migrations