schema_plus_foreign_keys 0.1.6 → 1.0.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 +5 -5
- data/.github/workflows/prs.yml +134 -0
- data/.gitignore +1 -0
- data/.simplecov +20 -0
- data/Gemfile +4 -1
- data/README.md +49 -35
- data/Rakefile +3 -1
- data/gemfiles/Gemfile.base +1 -1
- data/gemfiles/activerecord-5.2/Gemfile.base +4 -0
- data/gemfiles/activerecord-5.2/Gemfile.mysql2 +10 -0
- data/gemfiles/activerecord-5.2/Gemfile.postgresql +10 -0
- data/gemfiles/{activerecord-4.2.0 → activerecord-5.2}/Gemfile.sqlite3 +3 -3
- data/gemfiles/activerecord-6.0/Gemfile.base +4 -0
- data/gemfiles/activerecord-6.0/Gemfile.mysql2 +10 -0
- data/gemfiles/activerecord-6.0/Gemfile.postgresql +10 -0
- data/gemfiles/{activerecord-4.2.6 → activerecord-6.0}/Gemfile.sqlite3 +3 -3
- data/lib/schema_plus/foreign_keys/active_record/base.rb +2 -0
- data/lib/schema_plus/foreign_keys/active_record/connection_adapters/abstract/schema_creation.rb +20 -0
- data/lib/schema_plus/foreign_keys/active_record/connection_adapters/abstract_adapter.rb +9 -47
- data/lib/schema_plus/foreign_keys/active_record/connection_adapters/foreign_key_definition.rb +4 -35
- data/lib/schema_plus/foreign_keys/active_record/connection_adapters/mysql2_adapter.rb +15 -16
- data/lib/schema_plus/foreign_keys/active_record/connection_adapters/postgresql_adapter.rb +8 -6
- data/lib/schema_plus/foreign_keys/active_record/connection_adapters/sqlite3_adapter.rb +14 -6
- data/lib/schema_plus/foreign_keys/active_record/connection_adapters/table_definition.rb +10 -49
- data/lib/schema_plus/foreign_keys/active_record/migration/command_recorder.rb +4 -2
- data/lib/schema_plus/foreign_keys/middleware/dumper.rb +5 -3
- data/lib/schema_plus/foreign_keys/middleware/migration.rb +13 -5
- data/lib/schema_plus/foreign_keys/middleware/model.rb +2 -0
- data/lib/schema_plus/foreign_keys/middleware/mysql.rb +3 -1
- data/lib/schema_plus/foreign_keys/middleware/sql.rb +2 -15
- data/lib/schema_plus/foreign_keys/version.rb +3 -1
- data/lib/schema_plus/foreign_keys.rb +3 -1
- data/lib/schema_plus_foreign_keys.rb +2 -0
- data/schema_dev.yml +5 -4
- data/schema_plus_foreign_keys.gemspec +10 -8
- data/spec/deprecation_spec.rb +15 -112
- data/spec/foreign_key_definition_spec.rb +5 -3
- data/spec/foreign_key_spec.rb +26 -24
- data/spec/migration_spec.rb +73 -91
- data/spec/named_schemas_spec.rb +16 -14
- data/spec/schema_dumper_spec.rb +36 -35
- data/spec/spec_helper.rb +6 -4
- data/spec/support/reference.rb +3 -2
- metadata +48 -73
- data/.travis.yml +0 -24
- data/gemfiles/activerecord-4.2.0/Gemfile.base +0 -3
- data/gemfiles/activerecord-4.2.0/Gemfile.mysql2 +0 -10
- data/gemfiles/activerecord-4.2.0/Gemfile.postgresql +0 -10
- data/gemfiles/activerecord-4.2.1/Gemfile.base +0 -3
- data/gemfiles/activerecord-4.2.1/Gemfile.mysql2 +0 -10
- data/gemfiles/activerecord-4.2.1/Gemfile.postgresql +0 -10
- data/gemfiles/activerecord-4.2.1/Gemfile.sqlite3 +0 -10
- data/gemfiles/activerecord-4.2.6/Gemfile.base +0 -3
- data/gemfiles/activerecord-4.2.6/Gemfile.mysql2 +0 -10
- data/gemfiles/activerecord-4.2.6/Gemfile.postgresql +0 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 4320accfc977e0693af01ea8da225767890fe058a20e2fb38a5b3e17d96e5f8a
|
|
4
|
+
data.tar.gz: 7bb518bae024a887cefc969ec98b0c6b8c79f6818386e04362fe294622c7596c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8378363061d53b5f479c12e333489efb6206f47aaf259e50852346f437cd90662dc3efbbb2c2337ef562a29b5f4d92cdd8e5a3f2e7a8c015f70fdc1c5f2e6f3d
|
|
7
|
+
data.tar.gz: 4a67d8e35b227029cf1af8834d0e387afddded929504a78ccae97a65a0563a8e2bab34f179315a57e8d1990fc1d8544f1cf36cfb2574ec6740a2d92890d74420
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# This file was auto-generated by the schema_dev tool, based on the data in
|
|
2
|
+
# ./schema_dev.yml
|
|
3
|
+
# Please do not edit this file; any changes will be overwritten next time
|
|
4
|
+
# schema_dev gets run.
|
|
5
|
+
---
|
|
6
|
+
name: CI PR Builds
|
|
7
|
+
'on':
|
|
8
|
+
push:
|
|
9
|
+
branches:
|
|
10
|
+
- master
|
|
11
|
+
pull_request:
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ci-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
jobs:
|
|
16
|
+
test:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
strategy:
|
|
19
|
+
fail-fast: false
|
|
20
|
+
matrix:
|
|
21
|
+
ruby:
|
|
22
|
+
- '2.5'
|
|
23
|
+
- '2.7'
|
|
24
|
+
- '3.0'
|
|
25
|
+
activerecord:
|
|
26
|
+
- '5.2'
|
|
27
|
+
- '6.0'
|
|
28
|
+
db:
|
|
29
|
+
- mysql2
|
|
30
|
+
- sqlite3
|
|
31
|
+
- skip
|
|
32
|
+
dbversion:
|
|
33
|
+
- skip
|
|
34
|
+
exclude:
|
|
35
|
+
- ruby: '3.0'
|
|
36
|
+
activerecord: '5.2'
|
|
37
|
+
- db: skip
|
|
38
|
+
dbversion: skip
|
|
39
|
+
include:
|
|
40
|
+
- ruby: '2.5'
|
|
41
|
+
activerecord: '5.2'
|
|
42
|
+
db: postgresql
|
|
43
|
+
dbversion: '9.6'
|
|
44
|
+
- ruby: '2.5'
|
|
45
|
+
activerecord: '6.0'
|
|
46
|
+
db: postgresql
|
|
47
|
+
dbversion: '9.6'
|
|
48
|
+
- ruby: '2.7'
|
|
49
|
+
activerecord: '5.2'
|
|
50
|
+
db: postgresql
|
|
51
|
+
dbversion: '9.6'
|
|
52
|
+
- ruby: '2.7'
|
|
53
|
+
activerecord: '6.0'
|
|
54
|
+
db: postgresql
|
|
55
|
+
dbversion: '9.6'
|
|
56
|
+
- ruby: '3.0'
|
|
57
|
+
activerecord: '6.0'
|
|
58
|
+
db: postgresql
|
|
59
|
+
dbversion: '9.6'
|
|
60
|
+
env:
|
|
61
|
+
BUNDLE_GEMFILE: "${{ github.workspace }}/gemfiles/activerecord-${{ matrix.activerecord }}/Gemfile.${{ matrix.db }}"
|
|
62
|
+
MYSQL_DB_HOST: 127.0.0.1
|
|
63
|
+
MYSQL_DB_USER: root
|
|
64
|
+
MYSQL_DB_PASS: database
|
|
65
|
+
POSTGRESQL_DB_HOST: 127.0.0.1
|
|
66
|
+
POSTGRESQL_DB_USER: schema_plus_test
|
|
67
|
+
POSTGRESQL_DB_PASS: database
|
|
68
|
+
steps:
|
|
69
|
+
- uses: actions/checkout@v2
|
|
70
|
+
- name: Set up Ruby
|
|
71
|
+
uses: ruby/setup-ruby@v1
|
|
72
|
+
with:
|
|
73
|
+
ruby-version: "${{ matrix.ruby }}"
|
|
74
|
+
bundler-cache: true
|
|
75
|
+
- name: Run bundle update
|
|
76
|
+
run: bundle update
|
|
77
|
+
- name: Start Mysql
|
|
78
|
+
if: matrix.db == 'mysql2'
|
|
79
|
+
run: |
|
|
80
|
+
docker run --rm --detach \
|
|
81
|
+
-e MYSQL_ROOT_PASSWORD=$MYSQL_DB_PASS \
|
|
82
|
+
-p 3306:3306 \
|
|
83
|
+
--health-cmd "mysqladmin ping --host=127.0.0.1 --password=$MYSQL_DB_PASS --silent" \
|
|
84
|
+
--health-interval 5s \
|
|
85
|
+
--health-timeout 5s \
|
|
86
|
+
--health-retries 5 \
|
|
87
|
+
--name database mysql:5.6
|
|
88
|
+
- name: Start Postgresql
|
|
89
|
+
if: matrix.db == 'postgresql'
|
|
90
|
+
run: |
|
|
91
|
+
docker run --rm --detach \
|
|
92
|
+
-e POSTGRES_USER=$POSTGRESQL_DB_USER \
|
|
93
|
+
-e POSTGRES_PASSWORD=$POSTGRESQL_DB_PASS \
|
|
94
|
+
-p 5432:5432 \
|
|
95
|
+
--health-cmd "pg_isready -q" \
|
|
96
|
+
--health-interval 5s \
|
|
97
|
+
--health-timeout 5s \
|
|
98
|
+
--health-retries 5 \
|
|
99
|
+
--name database postgres:${{ matrix.dbversion }}
|
|
100
|
+
- name: Wait for database to start
|
|
101
|
+
if: "(matrix.db == 'postgresql' || matrix.db == 'mysql2')"
|
|
102
|
+
run: |
|
|
103
|
+
COUNT=0
|
|
104
|
+
ATTEMPTS=20
|
|
105
|
+
until [[ $COUNT -eq $ATTEMPTS ]]; do
|
|
106
|
+
[ "$(docker inspect -f {{.State.Health.Status}} database)" == "healthy" ] && break
|
|
107
|
+
echo $(( COUNT++ )) > /dev/null
|
|
108
|
+
sleep 2
|
|
109
|
+
done
|
|
110
|
+
- name: Create testing database
|
|
111
|
+
if: "(matrix.db == 'postgresql' || matrix.db == 'mysql2')"
|
|
112
|
+
run: bundle exec rake create_ci_database
|
|
113
|
+
- name: Run tests
|
|
114
|
+
run: bundle exec rake spec
|
|
115
|
+
- name: Shutdown database
|
|
116
|
+
if: always() && (matrix.db == 'postgresql' || matrix.db == 'mysql2')
|
|
117
|
+
run: docker stop database
|
|
118
|
+
- name: Coveralls Parallel
|
|
119
|
+
if: "${{ !env.ACT }}"
|
|
120
|
+
uses: coverallsapp/github-action@master
|
|
121
|
+
with:
|
|
122
|
+
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
|
123
|
+
flag-name: run-${{ matrix.ruby }}-${{ matrix.activerecord }}-${{ matrix.db }}-${{ matrix.dbversion }}
|
|
124
|
+
parallel: true
|
|
125
|
+
finish:
|
|
126
|
+
needs: test
|
|
127
|
+
runs-on: ubuntu-latest
|
|
128
|
+
steps:
|
|
129
|
+
- name: Coveralls Finished
|
|
130
|
+
if: "${{ !env.ACT }}"
|
|
131
|
+
uses: coverallsapp/github-action@master
|
|
132
|
+
with:
|
|
133
|
+
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
|
134
|
+
parallel-finished: true
|
data/.gitignore
CHANGED
data/.simplecov
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
SimpleCov.configure do
|
|
4
|
+
enable_coverage :branch
|
|
5
|
+
add_filter '/spec/'
|
|
6
|
+
|
|
7
|
+
add_group 'Binaries', '/bin/'
|
|
8
|
+
add_group 'Libraries', '/lib/'
|
|
9
|
+
|
|
10
|
+
if ENV['CI']
|
|
11
|
+
require 'simplecov-lcov'
|
|
12
|
+
|
|
13
|
+
SimpleCov::Formatter::LcovFormatter.config do |c|
|
|
14
|
+
c.report_with_single_file = true
|
|
15
|
+
c.single_report_path = 'coverage/lcov.info'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
formatter SimpleCov::Formatter::LcovFormatter
|
|
19
|
+
end
|
|
20
|
+
end
|
data/Gemfile
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
source "http://rubygems.org"
|
|
2
4
|
|
|
3
5
|
gemspec
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
gemfile_local = File.expand_path '../Gemfile.local', __FILE__
|
|
8
|
+
eval File.read(gemfile_local), binding, gemfile_local if File.exist? gemfile_local
|
data/README.md
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
[](http://badge.fury.io/rb/schema_plus_foreign_keys)
|
|
2
|
-
[](https://gemnasium.com/SchemaPlus/schema_plus_foreign_keys)
|
|
2
|
+
[](https://github.com/SchemaPlus/schema_plus_foreign_keys/actions)
|
|
3
|
+
[](https://coveralls.io/github/SchemaPlus/schema_plus_foreign_keys)
|
|
5
4
|
|
|
6
5
|
# SchemaPlus::ForeignKeys
|
|
7
6
|
|
|
8
|
-
SchemaPlus::ForeignKeys provides extended support in ActiveRecord. This includes extended support for
|
|
7
|
+
SchemaPlus::ForeignKeys provides extended support in ActiveRecord. This includes extended support for declaring
|
|
8
|
+
foreign key constraints in migrations; support for deferrable constraints; support for SQLite3; cleaner schema dumps.
|
|
9
9
|
|
|
10
|
-
SchemaPlus::ForeignKeys is part of the [SchemaPlus](https://github.com/SchemaPlus/) family of Ruby on Rails ActiveRecord
|
|
10
|
+
SchemaPlus::ForeignKeys is part of the [SchemaPlus](https://github.com/SchemaPlus/) family of Ruby on Rails ActiveRecord
|
|
11
|
+
extension gems.
|
|
11
12
|
|
|
12
|
-
For extra convenience, see also [schema_auto_foreign_keys](https://github.com/SchemaPlus/schema_auto_foreign_keys),
|
|
13
|
+
For extra convenience, see also [schema_auto_foreign_keys](https://github.com/SchemaPlus/schema_auto_foreign_keys),
|
|
14
|
+
which creates foriegn key constraints automatically.
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
## Installation
|
|
@@ -30,45 +32,50 @@ gem.add_dependency "schema_plus_foreign_keys" # in a .gemspec
|
|
|
30
32
|
### Migrations
|
|
31
33
|
|
|
32
34
|
To declare a foreign key constraint for a column, use the `:foreign_key`
|
|
33
|
-
option. The same options can be used with `t.integer`, `t.references`, `t.belongs_to`, `t.foreign_key`,
|
|
35
|
+
option. The same options can be used with `t.integer`, `t.references`, `t.belongs_to`, `t.foreign_key`,
|
|
36
|
+
`change_column`, and `add_foreign_key`:
|
|
34
37
|
|
|
35
|
-
t.
|
|
36
|
-
t.
|
|
37
|
-
t.
|
|
38
|
+
t.references :author, foreign_key: true # create a foreign_key to table "authors"
|
|
39
|
+
t.references :author, foreign_key: {} # create a foreign_key to table "authors"
|
|
40
|
+
t.references :author, foreign_key: false # don't create a constraint (this is the default)
|
|
38
41
|
t.integer :author, foreign_key: true # create a foreign_key to table "authors"
|
|
39
42
|
|
|
40
|
-
t.
|
|
43
|
+
t.references :parent, foreign_key: true # special column parent_id defaults to referencing its own table
|
|
41
44
|
|
|
42
45
|
Specify the target table and its primary key using the `:references` and `:primary_key`:
|
|
43
46
|
|
|
44
|
-
t.
|
|
47
|
+
t.references :author, foreign_key: { references: :authors } # the default
|
|
45
48
|
t.integer :author, foreign_key: { references: :authors } # the default
|
|
46
|
-
t.
|
|
47
|
-
t.
|
|
48
|
-
t.
|
|
49
|
-
t.
|
|
50
|
-
t.
|
|
49
|
+
t.references :author, foreign_key: { references: :people } # choose table name
|
|
50
|
+
t.references :author, foreign_key: { primary_key: :ssn] } # choose primary key
|
|
51
|
+
t.references :author, foreign_key: { references: :people, primary_key: :ssn] } # choose both
|
|
52
|
+
t.references :author, foreign_key: { references: [:people, :ssn] } # shortcut for both
|
|
53
|
+
t.references :author, foreign_key: { references: nil } # same as foreign_key: false
|
|
51
54
|
|
|
52
|
-
You can also specify other attributes:
|
|
55
|
+
You can also specify other attributes that are supported by Rails:
|
|
53
56
|
|
|
54
|
-
t.
|
|
55
|
-
t.
|
|
56
|
-
t.
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
t.references :author, foreign_key: { name: "my_fk" } # override default auto-generated constraint name
|
|
58
|
+
t.references :author, foreign_key: { on_delete: :cascade }
|
|
59
|
+
t.references :author, foreign_key: { on_update: :set_null }
|
|
60
|
+
|
|
61
|
+
In addition, support for deferrable constraints is implemented:
|
|
62
|
+
|
|
63
|
+
t.references :author, foreign_key: { deferrable: true }
|
|
64
|
+
t.references :author, foreign_key: { deferrable: :initially_deferred }
|
|
59
65
|
|
|
60
66
|
Of course the options can be combined:
|
|
61
67
|
|
|
62
|
-
t.
|
|
68
|
+
t.references :author, foreign_key: { references: :people, primary_key: :ssn, name: "my_fk", on_delet: :no_action }
|
|
63
69
|
|
|
64
70
|
|
|
65
71
|
As a shorthand, all options except `:name` can be specified without placing
|
|
66
72
|
them in a `foreign_key` hash, e.g.
|
|
67
73
|
|
|
68
|
-
t.
|
|
69
|
-
t.
|
|
74
|
+
t.references :author, on_delete: :cascade # shorthand for foreign_key: { on_delete: :cascade }
|
|
75
|
+
t.references :author, references: :people # shorthand for foreign_key: { references: :people }
|
|
70
76
|
|
|
71
|
-
To remove a foreign key constraint, you can either change the column, specifying `foreign_key: false`, or
|
|
77
|
+
To remove a foreign key constraint, you can either change the column, specifying `foreign_key: false`, or
|
|
78
|
+
use `migration.remove_foreign_key(table, column)`
|
|
72
79
|
|
|
73
80
|
### Introspection
|
|
74
81
|
|
|
@@ -129,11 +136,14 @@ foreign key options.
|
|
|
129
136
|
|
|
130
137
|
### Schema Dump
|
|
131
138
|
|
|
132
|
-
For clarity (and because it's required for SQLite3), in the generated `schema_dump.rb` file, the foreign key
|
|
139
|
+
For clarity (and because it's required for SQLite3), in the generated `schema_dump.rb` file, the foreign key
|
|
140
|
+
definitions are included within the table definitions.
|
|
133
141
|
|
|
134
142
|
This means that the tables are output sorted that a table is
|
|
135
|
-
defined before others that depend on it. If, however, there are
|
|
136
|
-
foreign key relations, this won't be possible; In that case some table definitions will include comments indicating
|
|
143
|
+
defined before others that depend on it. If, however, there are circular dependencies in the
|
|
144
|
+
foreign key relations, this won't be possible; In that case some table definitions will include comments indicating
|
|
145
|
+
a "forward reference" to a table that's farther down in the file, and the constraint will be defined once that table
|
|
146
|
+
is defined (this can never happen with SQLite3).
|
|
137
147
|
|
|
138
148
|
|
|
139
149
|
## Compatibility
|
|
@@ -142,14 +152,19 @@ SchemaPlus::ForeignKeys is tested on:
|
|
|
142
152
|
|
|
143
153
|
<!-- SCHEMA_DEV: MATRIX - begin -->
|
|
144
154
|
<!-- These lines are auto-generated by schema_dev based on schema_dev.yml -->
|
|
145
|
-
* ruby **2.
|
|
146
|
-
* ruby **2.
|
|
147
|
-
* ruby **2.
|
|
155
|
+
* ruby **2.5** with activerecord **5.2**, using **mysql2**, **sqlite3** or **postgresql:9.6**
|
|
156
|
+
* ruby **2.5** with activerecord **6.0**, using **mysql2**, **sqlite3** or **postgresql:9.6**
|
|
157
|
+
* ruby **2.7** with activerecord **5.2**, using **mysql2**, **sqlite3** or **postgresql:9.6**
|
|
158
|
+
* ruby **2.7** with activerecord **6.0**, using **mysql2**, **sqlite3** or **postgresql:9.6**
|
|
159
|
+
* ruby **3.0** with activerecord **6.0**, using **mysql2**, **sqlite3** or **postgresql:9.6**
|
|
148
160
|
|
|
149
161
|
<!-- SCHEMA_DEV: MATRIX - end -->
|
|
150
162
|
|
|
151
163
|
## History
|
|
152
164
|
|
|
165
|
+
* 1.0.0 - Drop Ruby < 2.5 and Rails < 5.2, adding Rails 6.0, and remove many deprecations
|
|
166
|
+
* 0.1.8 - Compatibility with ActiveRecord 5.1 and ActiveRecord 5.2.
|
|
167
|
+
* 0.1.7 - Compatibility with ActiveRecord 5.0.
|
|
153
168
|
* 0.1.6 - Missing require
|
|
154
169
|
* 0.1.5 - Explicit gem dependencies
|
|
155
170
|
* 0.1.4 - Upgrade schema_plus_core dependency
|
|
@@ -171,7 +186,7 @@ Some things to know about to help you develop and test:
|
|
|
171
186
|
* **schema_dev**: SchemaPlus::ForeignKeys uses [schema_dev](https://github.com/SchemaPlus/schema_dev) to
|
|
172
187
|
facilitate running rspec tests on the matrix of ruby, activerecord, and database
|
|
173
188
|
versions that the gem supports, both locally and on
|
|
174
|
-
[
|
|
189
|
+
[github actions](https://github.com/SchemaPlus/schema_plus_foreign_keys/actions)
|
|
175
190
|
|
|
176
191
|
To to run rspec locally on the full matrix, do:
|
|
177
192
|
|
|
@@ -183,7 +198,6 @@ Some things to know about to help you develop and test:
|
|
|
183
198
|
The matrix of configurations is specified in `schema_dev.yml` in
|
|
184
199
|
the project root.
|
|
185
200
|
|
|
186
|
-
|
|
187
201
|
<!-- SCHEMA_DEV: TEMPLATE USES SCHEMA_DEV - end -->
|
|
188
202
|
|
|
189
203
|
<!-- SCHEMA_DEV: TEMPLATE USES SCHEMA_PLUS_CORE - begin -->
|
data/Rakefile
CHANGED
data/gemfiles/Gemfile.base
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
eval
|
|
1
|
+
base_gemfile = File.expand_path('../Gemfile.base', __FILE__)
|
|
2
|
+
eval File.read(base_gemfile), binding, base_gemfile
|
|
3
3
|
|
|
4
4
|
platform :ruby do
|
|
5
5
|
gem "sqlite3"
|
|
@@ -7,4 +7,4 @@ end
|
|
|
7
7
|
|
|
8
8
|
platform :jruby do
|
|
9
9
|
gem 'activerecord-jdbcsqlite3-adapter', '>=1.3.0.beta2'
|
|
10
|
-
end
|
|
10
|
+
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
eval
|
|
1
|
+
base_gemfile = File.expand_path('../Gemfile.base', __FILE__)
|
|
2
|
+
eval File.read(base_gemfile), binding, base_gemfile
|
|
3
3
|
|
|
4
4
|
platform :ruby do
|
|
5
5
|
gem "sqlite3"
|
|
@@ -7,4 +7,4 @@ end
|
|
|
7
7
|
|
|
8
8
|
platform :jruby do
|
|
9
9
|
gem 'activerecord-jdbcsqlite3-adapter', '>=1.3.0.beta2'
|
|
10
|
-
end
|
|
10
|
+
end
|
data/lib/schema_plus/foreign_keys/active_record/connection_adapters/abstract/schema_creation.rb
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SchemaPlus
|
|
4
|
+
module Core
|
|
5
|
+
module ActiveRecord
|
|
6
|
+
module ConnectionAdapters
|
|
7
|
+
module AbstractAdapter
|
|
8
|
+
module SchemaCreation
|
|
9
|
+
|
|
10
|
+
def visit_ForeignKeyDefinition(o)
|
|
11
|
+
# schema_plus_foreign_keys already implements a superior
|
|
12
|
+
# conversion of ForeignKeyDefinitions to SQL
|
|
13
|
+
o.to_sql
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'abstract/schema_creation'
|
|
4
|
+
|
|
1
5
|
module SchemaPlus::ForeignKeys
|
|
2
6
|
module ActiveRecord
|
|
3
7
|
# SchemaPlus::ForeignKeys adds several methods to the connection adapter (as returned by ActiveRecordBase#connection). See AbstractAdapter for details.
|
|
@@ -20,27 +24,16 @@ module SchemaPlus::ForeignKeys
|
|
|
20
24
|
# constraints; they must be included in the table specification when
|
|
21
25
|
# it's created. If you're using Sqlite3, this method will raise an
|
|
22
26
|
# error.)
|
|
23
|
-
def add_foreign_key(
|
|
24
|
-
options = args.extract_options!
|
|
25
|
-
case args.length
|
|
26
|
-
when 2
|
|
27
|
-
from_table, to_table = args
|
|
28
|
-
when 4
|
|
29
|
-
ActiveSupport::Deprecation.warn "4-argument form of add_foreign_key is deprecated. use add_foreign_key(from_table, to_table, options)"
|
|
30
|
-
(from_table, column, to_table, primary_key) = args
|
|
31
|
-
options.merge!(column: column, primary_key: primary_key)
|
|
32
|
-
end
|
|
33
|
-
|
|
27
|
+
def add_foreign_key(from_table, to_table, **options) # (table_name, column, to_table, primary_key, options = {})
|
|
34
28
|
options = options.dup
|
|
35
29
|
options[:column] ||= foreign_key_column_for(to_table)
|
|
36
|
-
options[:name] ||= ForeignKeyDefinition.default_name(from_table, options[:column])
|
|
37
30
|
|
|
38
31
|
foreign_key_sql = add_foreign_key_sql(from_table, to_table, options)
|
|
39
32
|
execute "ALTER TABLE #{quote_table_name(from_table)} #{foreign_key_sql}"
|
|
40
33
|
end
|
|
41
34
|
|
|
42
35
|
# called directly by AT's bulk_change_table, for migration
|
|
43
|
-
# change_table :name, :
|
|
36
|
+
# change_table :name, bulk: true { ... }
|
|
44
37
|
def add_foreign_key_sql(from_table, to_table, options = {}) #:nodoc:
|
|
45
38
|
foreign_key = ::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(from_table, AbstractAdapter.proper_table_name(to_table), options)
|
|
46
39
|
"ADD #{foreign_key.to_sql}"
|
|
@@ -51,7 +44,7 @@ module SchemaPlus::ForeignKeys
|
|
|
51
44
|
end
|
|
52
45
|
|
|
53
46
|
def self.proper_table_name(name)
|
|
54
|
-
|
|
47
|
+
::ActiveRecord::Migration.new.proper_table_name(name)
|
|
55
48
|
end
|
|
56
49
|
|
|
57
50
|
# Remove a foreign key constraint
|
|
@@ -64,49 +57,18 @@ module SchemaPlus::ForeignKeys
|
|
|
64
57
|
# (NOTE: Sqlite3 does not support altering a table to remove
|
|
65
58
|
# foreign-key constraints. If you're using Sqlite3, this method will
|
|
66
59
|
# raise an error.)
|
|
67
|
-
def remove_foreign_key(
|
|
68
|
-
from_table, to_table, options = normalize_remove_foreign_key_args(*args)
|
|
60
|
+
def remove_foreign_key(from_table, to_table = nil, **options)
|
|
69
61
|
options[:column] ||= foreign_key_column_for(to_table)
|
|
70
62
|
if sql = remove_foreign_key_sql(from_table, to_table, options)
|
|
71
63
|
execute "ALTER TABLE #{quote_table_name(from_table)} #{sql}"
|
|
72
64
|
end
|
|
73
65
|
end
|
|
74
66
|
|
|
75
|
-
def normalize_remove_foreign_key_args(*args)
|
|
76
|
-
options = args.extract_options!
|
|
77
|
-
if options.has_key? :column_names
|
|
78
|
-
ActiveSupport::Deprecation.warn ":column_names option is deprecated, use :column"
|
|
79
|
-
options[:column] = options.delete(:column_names)
|
|
80
|
-
end
|
|
81
|
-
if options.has_key? :references_column_names
|
|
82
|
-
ActiveSupport::Deprecation.warn ":references_column_names option is deprecated, use :primary_key"
|
|
83
|
-
options[:primary_key] = options.delete(:references_column_names)
|
|
84
|
-
end
|
|
85
|
-
if options.has_key? :references_table_name
|
|
86
|
-
ActiveSupport::Deprecation.warn ":references_table_name option is deprecated, use :to_table"
|
|
87
|
-
options[:to_table] = options.delete(:references_table_name)
|
|
88
|
-
end
|
|
89
|
-
case args.length
|
|
90
|
-
when 1
|
|
91
|
-
from_table = args[0]
|
|
92
|
-
when 2
|
|
93
|
-
from_table, to_table = args
|
|
94
|
-
when 3, 4
|
|
95
|
-
ActiveSupport::Deprecation.warn "3- and 4-argument forms of remove_foreign_key are deprecated. use add_foreign_key(from_table, to_table, options)"
|
|
96
|
-
(from_table, column, to_table, primary_key) = args
|
|
97
|
-
options.merge!(column: column, primary_key: primary_key)
|
|
98
|
-
else
|
|
99
|
-
raise ArgumentError, "Wrong number of arguments(#{args.length}) to remove_foreign_key"
|
|
100
|
-
end
|
|
101
|
-
to_table ||= options.delete(:to_table)
|
|
102
|
-
[from_table, to_table, options]
|
|
103
|
-
end
|
|
104
|
-
|
|
105
67
|
def get_foreign_key_name(from_table, to_table, options)
|
|
106
68
|
return options[:name] if options[:name]
|
|
107
69
|
|
|
108
70
|
fks = foreign_keys(from_table)
|
|
109
|
-
if fks.detect
|
|
71
|
+
if fks.detect { |it| it.name == to_table }
|
|
110
72
|
ActiveSupport::Deprecation.warn "remove_foreign_key(table, name) is deprecated. use remove_foreign_key(table, name: name)"
|
|
111
73
|
return to_table
|
|
112
74
|
end
|
data/lib/schema_plus/foreign_keys/active_record/connection_adapters/foreign_key_definition.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
require 'active_record/connection_adapters/abstract/schema_definitions'
|
|
3
4
|
|
|
4
5
|
module SchemaPlus::ForeignKeys
|
|
@@ -17,28 +18,7 @@ module SchemaPlus::ForeignKeys
|
|
|
17
18
|
# true
|
|
18
19
|
# :initially_deferred
|
|
19
20
|
module ForeignKeyDefinition
|
|
20
|
-
|
|
21
|
-
def column_names
|
|
22
|
-
ActiveSupport::Deprecation.warn "ForeignKeyDefinition#column_names is deprecated, use Array.wrap(column)"
|
|
23
|
-
Array.wrap(column)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def references_column_names
|
|
27
|
-
ActiveSupport::Deprecation.warn "ForeignKeyDefinition#references_column_names is deprecated, use Array.wrap(primary_key)"
|
|
28
|
-
Array.wrap(primary_key)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def references_table_name
|
|
32
|
-
ActiveSupport::Deprecation.warn "ForeignKeyDefinition#references_table_name is deprecated, use #to_table"
|
|
33
|
-
to_table
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def table_name
|
|
37
|
-
ActiveSupport::Deprecation.warn "ForeignKeyDefinition#table_name is deprecated, use #from_table"
|
|
38
|
-
from_table
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
ACTIONS = { :cascade => "CASCADE", :restrict => "RESTRICT", :nullify => "SET NULL", :set_default => "SET DEFAULT", :no_action => "NO ACTION" }.freeze
|
|
21
|
+
ACTIONS = { cascade: "CASCADE", restrict: "RESTRICT", nullify: "SET NULL", set_default: "SET DEFAULT", no_action: "NO ACTION" }.freeze
|
|
42
22
|
ACTION_LOOKUP = ACTIONS.invert.freeze
|
|
43
23
|
|
|
44
24
|
def initialize(from_table, to_table, options={})
|
|
@@ -88,7 +68,7 @@ module SchemaPlus::ForeignKeys
|
|
|
88
68
|
end
|
|
89
69
|
|
|
90
70
|
def to_sql
|
|
91
|
-
sql = name ? "CONSTRAINT #{name} " : ""
|
|
71
|
+
sql = name ? +"CONSTRAINT #{name} " : +""
|
|
92
72
|
sql << "FOREIGN KEY (#{quoted_column_names.join(", ")}) REFERENCES #{quoted_to_table} (#{quoted_primary_keys.join(", ")})"
|
|
93
73
|
sql << " ON UPDATE #{ACTIONS[on_update]}" if on_update
|
|
94
74
|
sql << " ON DELETE #{ACTIONS[on_delete]}" if on_delete
|
|
@@ -109,17 +89,6 @@ module SchemaPlus::ForeignKeys
|
|
|
109
89
|
::ActiveRecord::Base.connection.quote_table_name(to_table)
|
|
110
90
|
end
|
|
111
91
|
|
|
112
|
-
def self.default_name(from_table, column)
|
|
113
|
-
name = "fk_#{fixup_schema_name(from_table)}_#{Array.wrap(column).join('_and_')}"
|
|
114
|
-
name = name.slice(0, 27) + "_" + OpenSSL::Digest::MD5.new.hexdigest(name) if name.length > 60
|
|
115
|
-
name
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def self.fixup_schema_name(table_name)
|
|
119
|
-
# replace . with _
|
|
120
|
-
table_name.to_s.gsub(/[.]/, '_')
|
|
121
|
-
end
|
|
122
|
-
|
|
123
92
|
def match(test)
|
|
124
93
|
return false unless from_table == test.from_table
|
|
125
94
|
[:to_table, :column].reject{ |attr| test.send(attr).blank? }.all? { |attr|
|