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
|
-
|
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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
3
|
+
module Foreigner
|
4
|
+
module ConnectionAdapters
|
5
|
+
module MysqlAdapter
|
6
|
+
include Foreigner::ConnectionAdapters::Sql2003
|
15
7
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
-
|
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
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
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
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.
|
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.
|
63
|
+
rubygems_version: 1.2.0
|
63
64
|
signing_key:
|
64
65
|
specification_version: 1
|
65
66
|
summary: Foreign keys for Rails migrations
|