activerecord-creating_foreign_keys 0.0.1 → 0.1.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.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/lib/active_record/connection_adapters/mysql2/creating_foreign_keys/connection_specification/resolver.rb +27 -0
- data/lib/active_record/connection_adapters/mysql2/creating_foreign_keys/schema_creation.rb +44 -0
- data/lib/active_record/connection_adapters/mysql2/creating_foreign_keys/schema_statements.rb +46 -0
- data/lib/active_record/creating_foreign_keys.rb +2 -6
- data/lib/active_record/creating_foreign_keys/version.rb +1 -1
- data/test/creating_foreign_keys_test.rb +9 -8
- data/test/dummy/config/database.yml +2 -12
- data/test/dummy/config/environments/test.rb +0 -5
- metadata +38 -9
- data/lib/active_record/creating_foreign_keys/schema_creation.rb +0 -36
- data/lib/active_record/creating_foreign_keys/schema_statements.rb +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c06fff634cc068ec8449ca21f37777916c634d13
|
4
|
+
data.tar.gz: 95170d1add06402710fd566787f429c910d98849
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ee9f77469c020933dc6d49d46be31e83f2686cd9d64174ab55fbfd97aea4034eb3b40becd76a02cdd0fbbb3a7d67bb508491ebbb1798aeb7085100dc56cd392
|
7
|
+
data.tar.gz: 770f36fe2067350aa19e3f27200a1d030cd977ec23449c422f368a191fac2c46dfbf81ee559059db0843984230d32e079cc18fe24b5f78b31f108fa28ca50459
|
data/README.md
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
[](https://badge.fury.io/rb/activerecord-creating_foreign_keys)
|
1
2
|
[](https://travis-ci.com/hamuyuuki/activerecord-creating_foreign_keys)
|
2
3
|
[](https://codeclimate.com/github/hamuyuuki/activerecord-creating_foreign_keys/maintainability)
|
3
4
|
[](https://codeclimate.com/github/hamuyuuki/activerecord-creating_foreign_keys/test_coverage)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
module Mysql2
|
6
|
+
module CreatingForeignKeys
|
7
|
+
module ConnectionSpecification
|
8
|
+
module Resolver
|
9
|
+
def spec(config)
|
10
|
+
connection_specification = super(config)
|
11
|
+
|
12
|
+
if connection_specification.config[:adapter] == "mysql2"
|
13
|
+
require "active_record/connection_adapters/mysql2/creating_foreign_keys/schema_creation"
|
14
|
+
require "active_record/connection_adapters/mysql2/creating_foreign_keys/schema_statements"
|
15
|
+
|
16
|
+
ActiveRecord::ConnectionAdapters::Mysql2Adapter::SchemaCreation.prepend(ActiveRecord::ConnectionAdapters::Mysql2::CreatingForeignKeys::SchemaCreation)
|
17
|
+
ActiveRecord::ConnectionAdapters::Mysql2Adapter.prepend(ActiveRecord::ConnectionAdapters::Mysql2::CreatingForeignKeys::SchemaStatements)
|
18
|
+
end
|
19
|
+
|
20
|
+
connection_specification
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
module Mysql2
|
6
|
+
module CreatingForeignKeys
|
7
|
+
module SchemaCreation
|
8
|
+
private
|
9
|
+
def visit_TableDefinition(o)
|
10
|
+
return super(o) if o.foreign_keys.empty?
|
11
|
+
|
12
|
+
name = o.name
|
13
|
+
create_sql = +"CREATE#{' TEMPORARY' if o.temporary} TABLE #{quote_table_name(name)} "
|
14
|
+
|
15
|
+
statements = o.columns.map { |c| accept c }
|
16
|
+
statements.concat(o.indexes.map { |column_name, options| index_in_create(name, column_name, options) })
|
17
|
+
statements.concat(o.foreign_keys.map { |to_table, options| foreign_key_in_create(o.name, to_table, options) })
|
18
|
+
|
19
|
+
create_sql << "(#{statements.join(', ')}) " if statements.present?
|
20
|
+
create_sql << "#{o.options}"
|
21
|
+
create_sql << " AS #{@conn.to_sql(o.as)}" if o.as
|
22
|
+
create_sql
|
23
|
+
end
|
24
|
+
|
25
|
+
def visit_ForeignKeyDefinition(o)
|
26
|
+
sql = +<<-SQL.strip_heredoc
|
27
|
+
CONSTRAINT #{quote_column_name(o.name)}
|
28
|
+
FOREIGN KEY (#{quote_column_name(o.column)})
|
29
|
+
REFERENCES #{quote_table_name(o.to_table)} (#{quote_column_name(o.primary_key)})
|
30
|
+
SQL
|
31
|
+
sql << " #{action_sql('DELETE', o.on_delete)}" if o.on_delete
|
32
|
+
sql << " #{action_sql('UPDATE', o.on_update)}" if o.on_update
|
33
|
+
sql
|
34
|
+
end
|
35
|
+
|
36
|
+
def foreign_key_in_create(from_table, to_table, options)
|
37
|
+
options = @conn.foreign_key_options(from_table, to_table, options)
|
38
|
+
accept ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(from_table, to_table, options)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
module Mysql2
|
6
|
+
module CreatingForeignKeys
|
7
|
+
module SchemaStatements
|
8
|
+
def create_table(table_name, options = {})
|
9
|
+
td = create_table_definition table_name, options[:temporary], options[:options], options[:as]
|
10
|
+
|
11
|
+
if options[:id] != false && !options[:as]
|
12
|
+
pk = options.fetch(:primary_key) do
|
13
|
+
Base.get_primary_key table_name.to_s.singularize
|
14
|
+
end
|
15
|
+
|
16
|
+
td.primary_key pk, options.fetch(:id, :primary_key), options
|
17
|
+
end
|
18
|
+
|
19
|
+
yield td if block_given?
|
20
|
+
|
21
|
+
if options[:force] && table_exists?(table_name)
|
22
|
+
drop_table(table_name, options)
|
23
|
+
end
|
24
|
+
|
25
|
+
result = execute schema_creation.accept td
|
26
|
+
|
27
|
+
unless supports_indexes_in_create?
|
28
|
+
td.indexes.each_pair do |column_name, index_options|
|
29
|
+
add_index(table_name, column_name, index_options)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
result
|
34
|
+
end
|
35
|
+
|
36
|
+
def foreign_key_options(from_table, to_table, options) # :nodoc:
|
37
|
+
options = options.dup
|
38
|
+
options[:column] ||= foreign_key_column_for(to_table)
|
39
|
+
options[:name] ||= foreign_key_name(from_table, options)
|
40
|
+
options
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -3,11 +3,7 @@
|
|
3
3
|
require "active_support/lazy_load_hooks"
|
4
4
|
|
5
5
|
ActiveSupport.on_load(:active_record) do
|
6
|
-
require "active_record/creating_foreign_keys/
|
7
|
-
require "active_record/creating_foreign_keys/schema_statements"
|
8
|
-
# TODO: Should research the not `require` way
|
9
|
-
require "active_record/connection_adapters/abstract_mysql_adapter"
|
6
|
+
require "active_record/connection_adapters/mysql2/creating_foreign_keys/connection_specification/resolver"
|
10
7
|
|
11
|
-
ActiveRecord::ConnectionAdapters::
|
12
|
-
ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(ActiveRecord::CreatingForeignKeys::SchemaStatements)
|
8
|
+
ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.prepend(ActiveRecord::ConnectionAdapters::Mysql2::CreatingForeignKeys::ConnectionSpecification::Resolver)
|
13
9
|
end
|
@@ -38,7 +38,7 @@ class CreatingForeignKeysTest < ActiveSupport::TestCase
|
|
38
38
|
|
39
39
|
# FIXME: this seems bad. we should probably have a better way to indicate
|
40
40
|
# the query was cached
|
41
|
-
return if
|
41
|
+
return if "CACHE" == values[:name]
|
42
42
|
|
43
43
|
self.class.log_all << sql
|
44
44
|
self.class.log << sql unless ignore =~ sql
|
@@ -46,7 +46,7 @@ class CreatingForeignKeysTest < ActiveSupport::TestCase
|
|
46
46
|
end
|
47
47
|
|
48
48
|
# ref: https://github.com/rails/rails/blob/4-2-stable/activerecord/test/cases/test_case.rb#L122
|
49
|
-
ActiveSupport::Notifications.subscribe(
|
49
|
+
ActiveSupport::Notifications.subscribe("sql.active_record", SQLCounter.new)
|
50
50
|
|
51
51
|
# ref: https://github.com/rails/rails/blob/4-2-stable/activerecord/test/cases/test_case.rb#L49L61
|
52
52
|
def assert_queries(num = 1, options = {})
|
@@ -63,6 +63,12 @@ class CreatingForeignKeysTest < ActiveSupport::TestCase
|
|
63
63
|
x
|
64
64
|
end
|
65
65
|
|
66
|
+
# ref: https://github.com/rails/rails/blob/4-2-stable/activerecord/test/cases/migration/references_foreign_key_test.rb#L7L10
|
67
|
+
setup do
|
68
|
+
@connection = ActiveRecord::Base.connection
|
69
|
+
@connection.create_table(:testing_parents, force: true)
|
70
|
+
end
|
71
|
+
|
66
72
|
# ref: https://github.com/rails/rails/blob/4-2-stable/activerecord/test/cases/migration/references_foreign_key_test.rb#L12L15
|
67
73
|
# https://github.com/rails/rails/blob/4-2-stable/activerecord/test/cases/test_case.rb#L8L10
|
68
74
|
teardown do
|
@@ -71,13 +77,8 @@ class CreatingForeignKeysTest < ActiveSupport::TestCase
|
|
71
77
|
SQLCounter.clear_log
|
72
78
|
end
|
73
79
|
|
74
|
-
# ref: https://github.com/rails/rails/
|
75
|
-
# https://github.com/rails/rails/pull/20009/files#diff-753b84de930c3ef1f329af181b7fd7b21957e5c022765ca81748cda3002eb58dR35-R42
|
80
|
+
# ref: https://github.com/rails/rails/pull/20009/files#diff-753b84de930c3ef1f329af181b7fd7b21957e5c022765ca81748cda3002eb58dR35-R42
|
76
81
|
test "foreign keys can be created in one query with MySQL" do
|
77
|
-
ActiveRecord::Base.establish_connection :mysql
|
78
|
-
@connection = ActiveRecord::Base.connection
|
79
|
-
@connection.create_table(:testing_parents, force: true)
|
80
|
-
|
81
82
|
assert_queries(1) do
|
82
83
|
@connection.create_table :testings do |t|
|
83
84
|
t.references :testing_parent, foreign_key: true
|
@@ -1,16 +1,6 @@
|
|
1
|
-
default: &default
|
2
|
-
database: test
|
3
|
-
|
4
1
|
test:
|
5
|
-
<<: *default
|
6
|
-
adapter: sqlite3
|
7
|
-
pool: 5
|
8
|
-
timeout: 5000
|
9
|
-
database: db/test.sqlite3
|
10
|
-
|
11
|
-
mysql:
|
12
|
-
<<: *default
|
13
2
|
adapter: mysql2
|
3
|
+
database: test
|
14
4
|
encoding: utf8
|
15
|
-
username: root
|
16
5
|
host: <%= ENV["CI"] ? "127.0.0.1" : "mysql" %>
|
6
|
+
username: root
|
@@ -26,11 +26,6 @@ Rails.application.configure do
|
|
26
26
|
# Disable request forgery protection in test environment.
|
27
27
|
config.action_controller.allow_forgery_protection = false
|
28
28
|
|
29
|
-
# Tell Action Mailer not to deliver emails to the real world.
|
30
|
-
# The :test delivery method accumulates sent emails in the
|
31
|
-
# ActionMailer::Base.deliveries array.
|
32
|
-
config.action_mailer.delivery_method = :test
|
33
|
-
|
34
29
|
# Randomize the order test cases are executed.
|
35
30
|
config.active_support.test_order = :random
|
36
31
|
|
metadata
CHANGED
@@ -1,29 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-creating_foreign_keys
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- hamuyuuki
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-11-
|
11
|
+
date: 2020-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 4.2.
|
19
|
+
version: 4.2.11
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 4.2.
|
26
|
+
version: 4.2.11
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 4.2.11
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 4.2.11
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: mysql2
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +52,20 @@ dependencies:
|
|
38
52
|
- - "~>"
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: 0.4.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: railties
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 4.2.11
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 4.2.11
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: rubocop
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,7 +150,7 @@ dependencies:
|
|
122
150
|
- - "~>"
|
123
151
|
- !ruby/object:Gem::Version
|
124
152
|
version: 1.3.0
|
125
|
-
description: "`activerecord-creating_foreign_keys`
|
153
|
+
description: "`activerecord-creating_foreign_keys` defines FOREIGN KEY Constraints
|
126
154
|
in a CREATE TABLE Statement."
|
127
155
|
email:
|
128
156
|
- 13702378+hamuyuuki@users.noreply.github.com
|
@@ -133,9 +161,10 @@ files:
|
|
133
161
|
- MIT-LICENSE
|
134
162
|
- README.md
|
135
163
|
- Rakefile
|
164
|
+
- lib/active_record/connection_adapters/mysql2/creating_foreign_keys/connection_specification/resolver.rb
|
165
|
+
- lib/active_record/connection_adapters/mysql2/creating_foreign_keys/schema_creation.rb
|
166
|
+
- lib/active_record/connection_adapters/mysql2/creating_foreign_keys/schema_statements.rb
|
136
167
|
- lib/active_record/creating_foreign_keys.rb
|
137
|
-
- lib/active_record/creating_foreign_keys/schema_creation.rb
|
138
|
-
- lib/active_record/creating_foreign_keys/schema_statements.rb
|
139
168
|
- lib/active_record/creating_foreign_keys/version.rb
|
140
169
|
- test/creating_foreign_keys_test.rb
|
141
170
|
- test/dummy/README.rdoc
|
@@ -196,7 +225,7 @@ rubyforge_project:
|
|
196
225
|
rubygems_version: 2.6.14.4
|
197
226
|
signing_key:
|
198
227
|
specification_version: 4
|
199
|
-
summary:
|
228
|
+
summary: Define FOREIGN KEY Constraints in a CREATE TABLE Statement
|
200
229
|
test_files:
|
201
230
|
- test/test_helper.rb
|
202
231
|
- test/creating_foreign_keys_test.rb
|
@@ -1,36 +0,0 @@
|
|
1
|
-
|
2
|
-
module ActiveRecord
|
3
|
-
module CreatingForeignKeys
|
4
|
-
module SchemaCreation
|
5
|
-
def visit_TableDefinition(o)
|
6
|
-
name = o.name
|
7
|
-
create_sql = "CREATE#{' TEMPORARY' if o.temporary} TABLE #{quote_table_name(name)} "
|
8
|
-
|
9
|
-
statements = o.columns.map { |c| accept c }
|
10
|
-
statements.concat(o.indexes.map { |column_name, options| index_in_create(name, column_name, options) })
|
11
|
-
statements.concat(o.foreign_keys.map { |to_table, options| foreign_key_in_create(o.name, to_table, options) })
|
12
|
-
|
13
|
-
create_sql << "(#{statements.join(', ')}) " if statements.present?
|
14
|
-
create_sql << "#{o.options}"
|
15
|
-
create_sql << " AS #{@conn.to_sql(o.as)}" if o.as
|
16
|
-
create_sql
|
17
|
-
end
|
18
|
-
|
19
|
-
def visit_ForeignKeyDefinition(o)
|
20
|
-
sql = <<-SQL.strip_heredoc
|
21
|
-
CONSTRAINT #{quote_column_name(o.name)}
|
22
|
-
FOREIGN KEY (#{quote_column_name(o.column)})
|
23
|
-
REFERENCES #{quote_table_name(o.to_table)} (#{quote_column_name(o.primary_key)})
|
24
|
-
SQL
|
25
|
-
sql << " #{action_sql('DELETE', o.on_delete)}" if o.on_delete
|
26
|
-
sql << " #{action_sql('UPDATE', o.on_update)}" if o.on_update
|
27
|
-
sql
|
28
|
-
end
|
29
|
-
|
30
|
-
def foreign_key_in_create(from_table, to_table, options)
|
31
|
-
options = @conn.foreign_key_options(from_table, to_table, options)
|
32
|
-
accept ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(from_table, to_table, options)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
|
2
|
-
module ActiveRecord
|
3
|
-
module CreatingForeignKeys
|
4
|
-
module SchemaStatements
|
5
|
-
def create_table(table_name, options = {})
|
6
|
-
td = create_table_definition table_name, options[:temporary], options[:options], options[:as]
|
7
|
-
|
8
|
-
if options[:id] != false && !options[:as]
|
9
|
-
pk = options.fetch(:primary_key) do
|
10
|
-
Base.get_primary_key table_name.to_s.singularize
|
11
|
-
end
|
12
|
-
|
13
|
-
td.primary_key pk, options.fetch(:id, :primary_key), options
|
14
|
-
end
|
15
|
-
|
16
|
-
yield td if block_given?
|
17
|
-
|
18
|
-
if options[:force] && table_exists?(table_name)
|
19
|
-
drop_table(table_name, options)
|
20
|
-
end
|
21
|
-
|
22
|
-
result = execute schema_creation.accept td
|
23
|
-
|
24
|
-
unless supports_indexes_in_create?
|
25
|
-
td.indexes.each_pair do |column_name, index_options|
|
26
|
-
add_index(table_name, column_name, index_options)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
result
|
31
|
-
end
|
32
|
-
|
33
|
-
def foreign_key_options(from_table, to_table, options) # :nodoc:
|
34
|
-
options = options.dup
|
35
|
-
options[:column] ||= foreign_key_column_for(to_table)
|
36
|
-
options[:name] ||= foreign_key_name(from_table, options)
|
37
|
-
options
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|