matthuhiggins-foreigner 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,133 +1,149 @@
1
1
  module Foreigner
2
- class ForeignKeyDefinition < Struct.new(:from_table, :to_table, :options) #:nodoc:
3
- end
4
-
5
- module TableDefinition
6
- class ForeignKey < Struct.new(:base, :to_table, :options)
7
- def to_sql
8
- base.foreign_key_definition(to_table, options)
9
- end
10
- alias to_s :to_sql
2
+ module ConnectionAdapters
3
+ class ForeignKeyDefinition < Struct.new(:from_table, :to_table, :options) #:nodoc:
11
4
  end
12
5
 
13
- def self.included(base)
14
- base.class_eval do
15
- include InstanceMethods
16
- alias_method_chain :references, :foreign_keys
17
- alias_method_chain :to_sql, :foreign_keys
6
+ module SchemaDefinitions
7
+ def self.included(base)
8
+ base::TableDefinition.class_eval do
9
+ include Foreigner::ConnectionAdapters::TableDefinition
10
+ end
11
+
12
+ base::Table.class_eval do
13
+ include Foreigner::ConnectionAdapters::Table
14
+ end
18
15
  end
19
16
  end
20
-
21
- module InstanceMethods
22
- # Adds a :foreign_key option to TableDefinition.references.
23
- # If :foreign_key is true, a foreign key constraint is added to the table.
24
- # You can also specify a hash, which is passed as foreign key options.
25
- #
26
- # ===== Examples
27
- # ====== Add goat_id column and a foreign key to the goats table.
28
- # t.references(:goat, :foreign_key => true)
29
- # ====== Add goat_id column and a cascading foreign key to the goats table.
30
- # t.references(:goat, :foreign_key => {:dependent => :delete})
31
- #
32
- # Note: No foreign key is created if :polymorphic => true is used.
33
- # Note: If no name is specified, the database driver creates one for you!
34
- def references_with_foreign_keys(*args)
35
- options = args.extract_options!
36
- fk_options = options.delete(:foreign_key)
37
-
38
- if fk_options && !options[:polymorphic]
39
- fk_options = {} if options[:foreign_key] == true
40
- args.each { |to_table| foreign_key(to_table, fk_options) }
17
+
18
+ module TableDefinition
19
+ class ForeignKey < Struct.new(:base, :to_table, :options)
20
+ def to_sql
21
+ base.foreign_key_definition(to_table, options)
41
22
  end
23
+ alias to_s :to_sql
24
+ end
42
25
 
43
- references_without_foreign_keys(*(args << options))
26
+ def self.included(base)
27
+ base.class_eval do
28
+ include InstanceMethods
29
+ alias_method_chain :references, :foreign_keys
30
+ alias_method_chain :to_sql, :foreign_keys
31
+ end
44
32
  end
45
33
 
46
- # Defines a foreign key for the table. +to_table+ can be a single Symbol, or
47
- # an Array of Symbols. See SchemaStatements#add_foreign_key
48
- #
49
- # ===== Examples
50
- # ====== Creating a simple foreign key
51
- # t.foreign_key(:people)
52
- # ====== Defining the column
53
- # t.foreign_key(:people, :column => :sender_id)
54
- # ====== Creating a named foreign key
55
- # t.foreign_key(:people, :column => :sender_id, :name => 'sender_foreign_key')
56
- def foreign_key(to_table, options = {})
57
- to_table = to_table.to_s.pluralize if ActiveRecord::Base.pluralize_table_names
58
- foreign_keys << ForeignKey.new(@base, to_table, options)
59
- end
60
-
61
- def to_sql_with_foreign_keys
62
- sql = to_sql_without_foreign_keys
63
- sql << ', ' << (foreign_keys * ', ') if foreign_keys.present?
64
- sql
65
- end
34
+ module InstanceMethods
35
+ # Adds a :foreign_key option to TableDefinition.references.
36
+ # If :foreign_key is true, a foreign key constraint is added to the table.
37
+ # You can also specify a hash, which is passed as foreign key options.
38
+ #
39
+ # ===== Examples
40
+ # ====== Add goat_id column and a foreign key to the goats table.
41
+ # t.references(:goat, :foreign_key => true)
42
+ # ====== Add goat_id column and a cascading foreign key to the goats table.
43
+ # t.references(:goat, :foreign_key => {:dependent => :delete})
44
+ #
45
+ # Note: No foreign key is created if :polymorphic => true is used.
46
+ # Note: If no name is specified, the database driver creates one for you!
47
+ def references_with_foreign_keys(*args)
48
+ options = args.extract_options!
49
+ fk_options = options.delete(:foreign_key)
50
+
51
+ if fk_options && !options[:polymorphic]
52
+ fk_options = {} if fk_options == true
53
+ args.each { |to_table| foreign_key(to_table, fk_options) }
54
+ end
55
+
56
+ references_without_foreign_keys(*(args << options))
57
+ end
58
+
59
+ # Defines a foreign key for the table. +to_table+ can be a single Symbol, or
60
+ # an Array of Symbols. See SchemaStatements#add_foreign_key
61
+ #
62
+ # ===== Examples
63
+ # ====== Creating a simple foreign key
64
+ # t.foreign_key(:people)
65
+ # ====== Defining the column
66
+ # t.foreign_key(:people, :column => :sender_id)
67
+ # ====== Creating a named foreign key
68
+ # t.foreign_key(:people, :column => :sender_id, :name => 'sender_foreign_key')
69
+ def foreign_key(to_table, options = {})
70
+ if @base.supports_foreign_keys?
71
+ to_table = to_table.to_s.pluralize if ActiveRecord::Base.pluralize_table_names
72
+ foreign_keys << ForeignKey.new(@base, to_table, options)
73
+ end
74
+ end
66
75
 
67
- private
68
- def foreign_keys
69
- @foreign_keys ||= []
76
+ def to_sql_with_foreign_keys
77
+ sql = to_sql_without_foreign_keys
78
+ sql << ', ' << (foreign_keys * ', ') if foreign_keys.present?
79
+ sql
70
80
  end
71
- end
72
- end
73
-
74
- module Table
75
- def self.included(base)
76
- base.class_eval do
77
- include InstanceMethods
78
- alias_method_chain :references, :foreign_keys
81
+
82
+ private
83
+ def foreign_keys
84
+ @foreign_keys ||= []
85
+ end
79
86
  end
80
87
  end
81
88
 
82
- module InstanceMethods
83
- # Adds a new foreign key to the table. +to_table+ can be a single Symbol, or
84
- # an Array of Symbols. See SchemaStatements#add_foreign_key
85
- #
86
- # ===== Examples
87
- # ====== Creating a simple foreign key
88
- # t.foreign_key(:people)
89
- # ====== Defining the column
90
- # t.foreign_key(:people, :column => :sender_id)
91
- # ====== Creating a named foreign key
92
- # t.foreign_key(:people, :column => :sender_id, :name => 'sender_foreign_key')
93
- def foreign_key(to_table, options = {})
94
- @base.add_foreign_key(@table_name, to_table, options)
89
+ module Table
90
+ def self.included(base)
91
+ base.class_eval do
92
+ include InstanceMethods
93
+ alias_method_chain :references, :foreign_keys
94
+ end
95
95
  end
96
+
97
+ module InstanceMethods
98
+ # Adds a new foreign key to the table. +to_table+ can be a single Symbol, or
99
+ # an Array of Symbols. See SchemaStatements#add_foreign_key
100
+ #
101
+ # ===== Examples
102
+ # ====== Creating a simple foreign key
103
+ # t.foreign_key(:people)
104
+ # ====== Defining the column
105
+ # t.foreign_key(:people, :column => :sender_id)
106
+ # ====== Creating a named foreign key
107
+ # t.foreign_key(:people, :column => :sender_id, :name => 'sender_foreign_key')
108
+ def foreign_key(to_table, options = {})
109
+ @base.add_foreign_key(@table_name, to_table, options)
110
+ end
96
111
 
97
- # Remove the given foreign key from the table.
98
- #
99
- # ===== Examples
100
- # ====== Remove the suppliers_company_id_fk in the suppliers table.
101
- # t.remove_foreign_key :companies
102
- # ====== Remove the foreign key named accounts_branch_id_fk in the accounts table.
103
- # remove_foreign_key :column => :branch_id
104
- # ====== Remove the foreign key named party_foreign_key in the accounts table.
105
- # remove_index :name => :party_foreign_key
106
- def remove_foreign_key(options = {})
107
- @base.remove_foreign_key(@table_name, options)
108
- end
112
+ # Remove the given foreign key from the table.
113
+ #
114
+ # ===== Examples
115
+ # ====== Remove the suppliers_company_id_fk in the suppliers table.
116
+ # t.remove_foreign_key :companies
117
+ # ====== Remove the foreign key named accounts_branch_id_fk in the accounts table.
118
+ # remove_foreign_key :column => :branch_id
119
+ # ====== Remove the foreign key named party_foreign_key in the accounts table.
120
+ # remove_index :name => :party_foreign_key
121
+ def remove_foreign_key(options = {})
122
+ @base.remove_foreign_key(@table_name, options)
123
+ end
109
124
 
110
- # Adds a :foreign_key option to TableDefinition.references.
111
- # If :foreign_key is true, a foreign key constraint is added to the table.
112
- # You can also specify a hash, which is passed as foreign key options.
113
- #
114
- # ===== Examples
115
- # ====== Add goat_id column and a foreign key to the goats table.
116
- # t.references(:goat, :foreign_key => true)
117
- # ====== Add goat_id column and a cascading foreign key to the goats table.
118
- # t.references(:goat, :foreign_key => {:dependent => :delete})
119
- #
120
- # Note: No foreign key is created if :polymorphic => true is used.
121
- def references_with_foreign_keys(*args)
122
- options = args.extract_options!
123
- polymorphic = options[:polymorphic]
124
- fk_options = options.delete(:foreign_key)
125
+ # Adds a :foreign_key option to TableDefinition.references.
126
+ # If :foreign_key is true, a foreign key constraint is added to the table.
127
+ # You can also specify a hash, which is passed as foreign key options.
128
+ #
129
+ # ===== Examples
130
+ # ====== Add goat_id column and a foreign key to the goats table.
131
+ # t.references(:goat, :foreign_key => true)
132
+ # ====== Add goat_id column and a cascading foreign key to the goats table.
133
+ # t.references(:goat, :foreign_key => {:dependent => :delete})
134
+ #
135
+ # Note: No foreign key is created if :polymorphic => true is used.
136
+ def references_with_foreign_keys(*args)
137
+ options = args.extract_options!
138
+ polymorphic = options[:polymorphic]
139
+ fk_options = options.delete(:foreign_key)
125
140
 
126
- references_without_foreign_keys(*(args << options))
141
+ references_without_foreign_keys(*(args << options))
127
142
 
128
- if fk_options && !polymorphic
129
- fk_options = {} if options[:foreign_key] == true
130
- args.each { |to_table| foreign_key(to_table, fk_options) }
143
+ if fk_options && !polymorphic
144
+ fk_options = {} if fk_options == true
145
+ args.each { |to_table| foreign_key(to_table, fk_options) }
146
+ end
131
147
  end
132
148
  end
133
149
  end
@@ -1,62 +1,72 @@
1
1
  module Foreigner
2
- module AdapterMethods
3
- def supports_foreign_keys?
4
- false
2
+ module ConnectionAdapters
3
+ module SchemaStatements
4
+ def self.included(base)
5
+ base::AbstractAdapter.class_eval do
6
+ include Foreigner::ConnectionAdapters::AbstractAdapter
7
+ end
8
+ end
5
9
  end
6
10
 
7
- # Adds a new foreign key to the +from_table+, referencing the primary key of +to_table+
8
- #
9
- # The foreign key will be named after the from and to tables unless you pass
10
- # <tt>:name</tt> as an option.
11
- #
12
- # ===== Examples
13
- # ====== Creating a foreign key
14
- # add_foreign_key(:comments, :posts)
15
- # generates
16
- # ALTER TABLE `comments` ADD CONSTRAINT
17
- # `comments_post_id_fk` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`)
18
- #
19
- # ====== Creating a named foreign key
20
- # add_foreign_key(:comments, :posts, :name => 'comments_belongs_to_posts')
21
- # generates
22
- # ALTER TABLE `comments` ADD CONSTRAINT
23
- # `comments_belongs_to_posts` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`)
24
- #
25
- # ====== Creating a cascading foreign_key on a custom column
26
- # add_foreign_key(:people, :people, :column => 'best_friend_id', :dependent => :nullify)
27
- # generates
28
- # ALTER TABLE `people` ADD CONSTRAINT
29
- # `people_best_friend_id_fk` FOREIGN KEY (`best_friend_id`) REFERENCES `people` (`id`)
30
- # ON DELETE SET NULL
31
- #
32
- # === Supported options
33
- # [:column]
34
- # Specify the column name on the from_table that references the to_table. By default this is guessed
35
- # to be the singular name of the to_table with "_id" suffixed. So a to_table of :posts will use "post_id"
36
- # as the default <tt>:column</tt>.
37
- # [:name]
38
- # Specify the name of the foreign key constraint. This defaults to use from_table and foreign key column.
39
- # [:dependent]
40
- # If set to <tt>:delete</tt>, the associated records in from_table are deleted when records in to_table table are deleted.
41
- # If set to <tt>:nullify</tt>, the foreign key column is set to +NULL+.
42
- def add_foreign_key(from_table, to_table, options = {})
43
- end
44
-
45
- # Remove the given foreign key from the table.
46
- #
47
- # ===== Examples
48
- # ====== Remove the suppliers_company_id_fk in the suppliers table.
49
- # remove_foreign_key :suppliers, :companies
50
- # ====== Remove the foreign key named accounts_branch_id_fk in the accounts table.
51
- # remove_foreign_key :accounts, :column => :branch_id
52
- # ====== Remove the foreign key named party_foreign_key in the accounts table.
53
- # remove_foreign_key :accounts, :name => :party_foreign_key
54
- def remove_foreign_key(from_table, options)
55
- end
56
-
57
- # Return the foreign keys for the schema_dumper
58
- def foreign_keys(table_name)
59
- []
11
+ module AbstractAdapter
12
+ def supports_foreign_keys?
13
+ false
14
+ end
15
+
16
+ # Adds a new foreign key to the +from_table+, referencing the primary key of +to_table+
17
+ #
18
+ # The foreign key will be named after the from and to tables unless you pass
19
+ # <tt>:name</tt> as an option.
20
+ #
21
+ # ===== Examples
22
+ # ====== Creating a foreign key
23
+ # add_foreign_key(:comments, :posts)
24
+ # generates
25
+ # ALTER TABLE `comments` ADD CONSTRAINT
26
+ # `comments_post_id_fk` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`)
27
+ #
28
+ # ====== Creating a named foreign key
29
+ # add_foreign_key(:comments, :posts, :name => 'comments_belongs_to_posts')
30
+ # generates
31
+ # ALTER TABLE `comments` ADD CONSTRAINT
32
+ # `comments_belongs_to_posts` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`)
33
+ #
34
+ # ====== Creating a cascading foreign_key on a custom column
35
+ # add_foreign_key(:people, :people, :column => 'best_friend_id', :dependent => :nullify)
36
+ # generates
37
+ # ALTER TABLE `people` ADD CONSTRAINT
38
+ # `people_best_friend_id_fk` FOREIGN KEY (`best_friend_id`) REFERENCES `people` (`id`)
39
+ # ON DELETE SET NULL
40
+ #
41
+ # === Supported options
42
+ # [:column]
43
+ # Specify the column name on the from_table that references the to_table. By default this is guessed
44
+ # to be the singular name of the to_table with "_id" suffixed. So a to_table of :posts will use "post_id"
45
+ # as the default <tt>:column</tt>.
46
+ # [:name]
47
+ # Specify the name of the foreign key constraint. This defaults to use from_table and foreign key column.
48
+ # [:dependent]
49
+ # If set to <tt>:delete</tt>, the associated records in from_table are deleted when records in to_table table are deleted.
50
+ # If set to <tt>:nullify</tt>, the foreign key column is set to +NULL+.
51
+ def add_foreign_key(from_table, to_table, options = {})
52
+ end
53
+
54
+ # Remove the given foreign key from the table.
55
+ #
56
+ # ===== Examples
57
+ # ====== Remove the suppliers_company_id_fk in the suppliers table.
58
+ # remove_foreign_key :suppliers, :companies
59
+ # ====== Remove the foreign key named accounts_branch_id_fk in the accounts table.
60
+ # remove_foreign_key :accounts, :column => :branch_id
61
+ # ====== Remove the foreign key named party_foreign_key in the accounts table.
62
+ # remove_foreign_key :accounts, :name => :party_foreign_key
63
+ def remove_foreign_key(from_table, options)
64
+ end
65
+
66
+ # Return the foreign keys for the schema_dumper
67
+ def foreign_keys(table_name)
68
+ []
69
+ end
60
70
  end
61
71
  end
62
72
  end
@@ -6,8 +6,6 @@ module Foreigner
6
6
  include Foreigner::ConnectionAdapters::Sql2003
7
7
 
8
8
  def foreign_keys(table_name)
9
- foreign_keys = []
10
-
11
9
  fk_info = select_all %{
12
10
  select tc.constraint_name as name
13
11
  ,ccu.table_name as to_table
@@ -15,17 +13,11 @@ module Foreigner
15
13
  ,rc.delete_rule as dependency
16
14
  from information_schema.table_constraints tc
17
15
  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
16
+ using (constraint_catalog, constraint_schema, constraint_name)
21
17
  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
18
+ using (constraint_catalog, constraint_schema, constraint_name)
25
19
  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
20
+ using (constraint_catalog, constraint_schema, constraint_name)
29
21
  where tc.constraint_type = 'FOREIGN KEY'
30
22
  and tc.constraint_catalog = '#{@config[:database]}'
31
23
  and tc.table_name = '#{table_name}'
data/lib/foreigner.rb CHANGED
@@ -4,17 +4,8 @@ require 'foreigner/schema_dumper'
4
4
 
5
5
  module ActiveRecord
6
6
  module ConnectionAdapters
7
- AbstractAdapter.class_eval do
8
- include Foreigner::AdapterMethods
9
- end
10
-
11
- TableDefinition.class_eval do
12
- include Foreigner::TableDefinition
13
- end
14
-
15
- Table.class_eval do
16
- include Foreigner::Table
17
- end
7
+ include Foreigner::ConnectionAdapters::SchemaStatements
8
+ include Foreigner::ConnectionAdapters::SchemaDefinitions
18
9
  end
19
10
 
20
11
  SchemaDumper.class_eval do
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.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Higgins
@@ -38,6 +38,7 @@ files:
38
38
  - test/mysql_adapter_test.rb
39
39
  has_rdoc: false
40
40
  homepage: http://github.com/matthuhiggins/foreigner/tree/master
41
+ licenses:
41
42
  post_install_message:
42
43
  rdoc_options:
43
44
  - --line-numbers
@@ -60,7 +61,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
60
61
  requirements: []
61
62
 
62
63
  rubyforge_project: foreigner
63
- rubygems_version: 1.2.0
64
+ rubygems_version: 1.3.5
64
65
  signing_key:
65
66
  specification_version: 1
66
67
  summary: Foreign keys for Rails migrations