matthuhiggins-foreigner 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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