matthuhiggins-foreigner 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -16,7 +16,7 @@ Install as a plugin:
16
16
 
17
17
  Install as a gem by adding the following to environment.rb:
18
18
 
19
- config.gem "matthuhiggins-foreigner", :lib => "foreigner"
19
+ config.gem "matthuhiggins-foreigner", :lib => "foreigner", :source => http://gemcutter.org
20
20
 
21
21
  API
22
22
  ---
@@ -66,6 +66,8 @@ module Foreigner
66
66
  # t.foreign_key(:people, :column => :sender_id)
67
67
  # ====== Creating a named foreign key
68
68
  # t.foreign_key(:people, :column => :sender_id, :name => 'sender_foreign_key')
69
+ # ====== Defining the column of the +to_table+.
70
+ # t.foreign_key(:people, :column => :sender_id, :primary_key => :person_id)
69
71
  def foreign_key(to_table, options = {})
70
72
  if @base.supports_foreign_keys?
71
73
  to_table = to_table.to_s.pluralize if ActiveRecord::Base.pluralize_table_names
@@ -105,6 +107,8 @@ module Foreigner
105
107
  # t.foreign_key(:people, :column => :sender_id)
106
108
  # ====== Creating a named foreign key
107
109
  # t.foreign_key(:people, :column => :sender_id, :name => 'sender_foreign_key')
110
+ # ====== Defining the column of the +to_table+.
111
+ # t.foreign_key(:people, :column => :sender_id, :primary_key => :person_id)
108
112
  def foreign_key(to_table, options = {})
109
113
  @base.add_foreign_key(@table_name, to_table, options)
110
114
  end
@@ -43,6 +43,9 @@ module Foreigner
43
43
  # Specify the column name on the from_table that references the to_table. By default this is guessed
44
44
  # to be the singular name of the to_table with "_id" suffixed. So a to_table of :posts will use "post_id"
45
45
  # as the default <tt>:column</tt>.
46
+ # [:primary_key]
47
+ # Specify the column name on the to_table that is referenced by this foreign key. By default this is
48
+ # assumed to be "id".
46
49
  # [:name]
47
50
  # Specify the name of the foreign key constraint. This defaults to use from_table and foreign key column.
48
51
  # [:dependent]
@@ -1,14 +1,22 @@
1
- require 'foreigner/connection_adapters/sql_2003'
2
-
3
1
  module Foreigner
4
2
  module ConnectionAdapters
5
3
  module MysqlAdapter
6
4
  include Foreigner::ConnectionAdapters::Sql2003
7
5
 
6
+ def remove_foreign_key(table, options)
7
+ if Hash === options
8
+ foreign_key_name = foreign_key_name(table, options[:column], options)
9
+ else
10
+ foreign_key_name = foreign_key_name(table, "#{options.to_s.singularize}_id")
11
+ end
12
+
13
+ execute "ALTER TABLE #{quote_table_name(table)} DROP FOREIGN KEY #{quote_column_name(foreign_key_name)}"
14
+ end
15
+
8
16
  def foreign_keys(table_name)
9
- foreign_keys = []
10
17
  fk_info = select_all %{
11
18
  SELECT fk.referenced_table_name as 'to_table'
19
+ ,fk.referenced_column_name as 'primary_key'
12
20
  ,fk.column_name as 'column'
13
21
  ,fk.constraint_name as 'name'
14
22
  FROM information_schema.key_column_usage fk
@@ -19,8 +27,9 @@ module Foreigner
19
27
 
20
28
  create_table_info = select_one("SHOW CREATE TABLE #{quote_table_name(table_name)}")["Create Table"]
21
29
 
22
- fk_info.each do |row|
23
- options = {:column => row['column'], :name => row['name']}
30
+ fk_info.map do |row|
31
+ options = {:column => row['column'], :name => row['name'], :primary_key => row['primary_key']}
32
+
24
33
  if create_table_info =~ /CONSTRAINT #{quote_column_name(row['name'])} FOREIGN KEY .* REFERENCES .* ON DELETE (CASCADE|SET NULL)/
25
34
  if $1 == 'CASCADE'
26
35
  options[:dependent] = :delete
@@ -28,10 +37,8 @@ module Foreigner
28
37
  options[:dependent] = :nullify
29
38
  end
30
39
  end
31
- foreign_keys << ForeignKeyDefinition.new(table_name, row['to_table'], options)
40
+ ForeignKeyDefinition.new(table_name, row['to_table'], options)
32
41
  end
33
-
34
- foreign_keys
35
42
  end
36
43
  end
37
44
  end
@@ -1,36 +1,46 @@
1
- require 'foreigner/connection_adapters/sql_2003'
2
-
3
1
  module Foreigner
4
2
  module ConnectionAdapters
5
3
  module PostgreSQLAdapter
6
4
  include Foreigner::ConnectionAdapters::Sql2003
5
+
6
+ def remove_foreign_key(table, options)
7
+ if Hash === options
8
+ foreign_key_name = foreign_key_name(table, options[:column], options)
9
+ else
10
+ foreign_key_name = foreign_key_name(table, "#{options.to_s.singularize}_id")
11
+ end
12
+
13
+ execute "ALTER TABLE #{quote_table_name(table)} DROP CONSTRAINT #{quote_column_name(foreign_key_name)}"
14
+ end
7
15
 
8
16
  def foreign_keys(table_name)
9
17
  fk_info = select_all %{
10
- select tc.constraint_name as name
18
+ SELECT tc.constraint_name as name
11
19
  ,ccu.table_name as to_table
20
+ ,ccu.column_name as primary_key
12
21
  ,kcu.column_name as column
13
22
  ,rc.delete_rule as dependency
14
- from information_schema.table_constraints tc
15
- join information_schema.key_column_usage kcu
16
- using (constraint_catalog, constraint_schema, constraint_name)
17
- join information_schema.referential_constraints rc
18
- using (constraint_catalog, constraint_schema, constraint_name)
19
- join information_schema.constraint_column_usage ccu
20
- using (constraint_catalog, constraint_schema, constraint_name)
21
- where tc.constraint_type = 'FOREIGN KEY'
22
- and tc.constraint_catalog = '#{@config[:database]}'
23
- and tc.table_name = '#{table_name}'
23
+ FROM information_schema.table_constraints tc
24
+ JOIN information_schema.key_column_usage kcu
25
+ USING (constraint_catalog, constraint_schema, constraint_name)
26
+ JOIN information_schema.referential_constraints rc
27
+ USING (constraint_catalog, constraint_schema, constraint_name)
28
+ JOIN information_schema.constraint_column_usage ccu
29
+ USING (constraint_catalog, constraint_schema, constraint_name)
30
+ WHERE tc.constraint_type = 'FOREIGN KEY'
31
+ AND tc.constraint_catalog = '#{@config[:database]}'
32
+ AND tc.table_name = '#{table_name}'
24
33
  }
25
34
 
26
- fk_info.inject([]) do |foreign_keys, row|
27
- options = {:column => row['column'], :name => row['name']}
35
+ fk_info.map do |row|
36
+ options = {:column => row['column'], :name => row['name'], :primary_key => row['primary_key']}
37
+
28
38
  if row['dependency'] == 'CASCADE'
29
39
  options[:dependent] = :delete
30
40
  elsif row['dependency'] == 'SET NULL'
31
41
  options[:dependent] = :nullify
32
42
  end
33
- foreign_keys << ForeignKeyDefinition.new(table_name, row['to_table'], options)
43
+ ForeignKeyDefinition.new(table_name, row['to_table'], options)
34
44
  end
35
45
  end
36
46
  end
@@ -19,23 +19,14 @@ module Foreigner
19
19
 
20
20
  def foreign_key_definition(to_table, options = {})
21
21
  column = options[:column] || "#{to_table.to_s.singularize}_id"
22
+ primary_key = options[:primary_key] || "id"
22
23
  dependency = dependency_sql(options[:dependent])
23
24
 
24
- sql = "FOREIGN KEY (#{quote_column_name(column)}) REFERENCES #{quote_table_name(to_table)}(id)"
25
+ sql = "FOREIGN KEY (#{quote_column_name(column)}) REFERENCES #{quote_table_name(to_table)}(#{primary_key})"
25
26
  sql << " #{dependency}" unless dependency.blank?
26
27
  sql
27
28
  end
28
29
 
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
30
  private
40
31
  def foreign_key_name(table, column, options = {})
41
32
  if options[:name]
@@ -21,8 +21,14 @@ module Foreigner
21
21
  add_foreign_key_statements = foreign_keys.map do |foreign_key|
22
22
  statement_parts = [ ('add_foreign_key ' + foreign_key.from_table.inspect) ]
23
23
  statement_parts << foreign_key.to_table.inspect
24
- statement_parts << (':column => ' + foreign_key.options[:column].inspect)
25
24
  statement_parts << (':name => ' + foreign_key.options[:name].inspect)
25
+
26
+ if foreign_key.options[:column] != "#{foreign_key.to_table.singularize}_id"
27
+ statement_parts << (':column => ' + foreign_key.options[:column].inspect)
28
+ end
29
+ if foreign_key.options[:primary_key] != 'id'
30
+ statement_parts << (':primary_key => ' + foreign_key.options[:primary_key].inspect)
31
+ end
26
32
  if foreign_key.options[:dependent].present?
27
33
  statement_parts << (':dependent => ' + foreign_key.options[:dependent].inspect)
28
34
  end
data/lib/foreigner.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'foreigner/connection_adapters/abstract/schema_statements'
2
2
  require 'foreigner/connection_adapters/abstract/schema_definitions'
3
+ require 'foreigner/connection_adapters/sql_2003'
3
4
  require 'foreigner/schema_dumper'
4
5
 
5
6
  module ActiveRecord
@@ -13,7 +14,7 @@ module ActiveRecord
13
14
  end
14
15
 
15
16
  Base.class_eval do
16
- if ['MySQL', 'PostgreSQL'].include? connection.adapter_name
17
+ if %w(MySQL PostgreSQL).include? connection.adapter_name
17
18
  require "foreigner/connection_adapters/#{connection.adapter_name.downcase}_adapter"
18
19
  end
19
20
  end
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.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Higgins
@@ -26,9 +26,7 @@ files:
26
26
  - Rakefile
27
27
  - README
28
28
  - lib/foreigner.rb
29
- - lib/foreigner
30
29
  - lib/foreigner/schema_dumper.rb
31
- - lib/foreigner/connection_adapters
32
30
  - lib/foreigner/connection_adapters/sql_2003.rb
33
31
  - lib/foreigner/connection_adapters/mysql_adapter.rb
34
32
  - lib/foreigner/connection_adapters/postgresql_adapter.rb
@@ -36,9 +34,10 @@ files:
36
34
  - lib/foreigner/connection_adapters/abstract/schema_statements.rb
37
35
  - test/helper.rb
38
36
  - test/mysql_adapter_test.rb
39
- has_rdoc: false
37
+ has_rdoc: true
40
38
  homepage: http://github.com/matthuhiggins/foreigner/tree/master
41
- licenses:
39
+ licenses: []
40
+
42
41
  post_install_message:
43
42
  rdoc_options:
44
43
  - --line-numbers
@@ -60,7 +59,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
60
59
  version:
61
60
  requirements: []
62
61
 
63
- rubyforge_project: foreigner
62
+ rubyforge_project:
64
63
  rubygems_version: 1.3.5
65
64
  signing_key:
66
65
  specification_version: 1