ridgepole 0.8.10 → 0.8.11
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/.rubocop.yml +9 -34
- data/README.md +3 -0
- data/lib/ridgepole/dsl_parser.rb +2 -1
- data/lib/ridgepole/dsl_parser/context.rb +1 -1
- data/lib/ridgepole/dsl_parser/table_definition.rb +7 -0
- data/lib/ridgepole/ext/abstract_mysql_adapter/use_alter_index.rb +1 -1
- data/lib/ridgepole/version.rb +1 -1
- data/ridgepole.gemspec +1 -1
- data/spec/erb_helper.rb +4 -4
- data/spec/mysql/collation/collation_spec.rb +1 -1
- data/spec/mysql/fk/migrate_create_fk_spec.rb +53 -0
- data/spec/mysql/migrate/migrate_change_column3_spec.rb +122 -0
- data/spec/spec_condition.rb +4 -0
- data/spec/spec_helper.rb +2 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 367dff4faf9fd7e94588cdefe290cf13953cf82b9dc5110e91cfd5d4ee2507a3
|
4
|
+
data.tar.gz: 20ad65390cd7b12fe97e8fbae409aa5bc0d86a6c73c79a9916bfc55f46f03cb6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94039eb4e75e2f0b218275ffec9b8a1b4c28ae5b9c93ad64b584793acbabc1ece9eb8ddde4e6d3097ffc6a9346ef36a6318334048d99c8e85050e0b9ef3088bd
|
7
|
+
data.tar.gz: 5e4837104ea5b6b69e42fdcc82e29b71a33835ce8371b959c16f3c00b014047a88b3c01ecba74ab8d6e591fd3357d15019a1dc41c425ff4c10b49fcec6bbdc48
|
data/.rubocop.yml
CHANGED
@@ -3,6 +3,7 @@ AllCops:
|
|
3
3
|
- 'gemfiles/**/*'
|
4
4
|
- 'omnibus-ridgepole/**/*'
|
5
5
|
TargetRubyVersion: 2.4
|
6
|
+
NewCops: enable
|
6
7
|
Bundler/OrderedGems:
|
7
8
|
Include:
|
8
9
|
- 'Appraisals'
|
@@ -39,39 +40,13 @@ Layout/ClosingHeredocIndentation:
|
|
39
40
|
Enabled: false
|
40
41
|
Style/NumericPredicate:
|
41
42
|
Enabled: false
|
42
|
-
Layout/EmptyLinesAroundAttributeAccessor:
|
43
|
-
Enabled: true
|
44
|
-
Layout/SpaceAroundMethodCallOperator:
|
45
|
-
Enabled: true
|
46
|
-
Lint/DeprecatedOpenSSLConstant:
|
47
|
-
Enabled: true
|
48
43
|
Lint/MissingSuper:
|
49
44
|
Enabled: false
|
50
|
-
|
51
|
-
Enabled:
|
52
|
-
|
53
|
-
Enabled:
|
54
|
-
Lint/
|
55
|
-
Enabled:
|
56
|
-
Style/
|
57
|
-
Enabled:
|
58
|
-
Style/BisectedAttrAccessor:
|
59
|
-
Enabled: true
|
60
|
-
Style/ExponentialNotation:
|
61
|
-
Enabled: true
|
62
|
-
Style/HashEachMethods:
|
63
|
-
Enabled: true
|
64
|
-
Style/HashTransformKeys:
|
65
|
-
Enabled: true
|
66
|
-
Style/HashTransformValues:
|
67
|
-
Enabled: true
|
68
|
-
Style/RedundantAssignment:
|
69
|
-
Enabled: true
|
70
|
-
Style/RedundantFetchBlock:
|
71
|
-
Enabled: true
|
72
|
-
Style/RedundantRegexpCharacterClass:
|
73
|
-
Enabled: true
|
74
|
-
Style/RedundantRegexpEscape:
|
75
|
-
Enabled: true
|
76
|
-
Style/SlicingWithRange:
|
77
|
-
Enabled: true
|
45
|
+
Style/StringConcatenation:
|
46
|
+
Enabled: false
|
47
|
+
Style/SoleNestedConditional:
|
48
|
+
Enabled: false
|
49
|
+
Lint/DuplicateBranch:
|
50
|
+
Enabled: false
|
51
|
+
Style/OptionalBooleanParameter:
|
52
|
+
Enabled: false
|
data/README.md
CHANGED
@@ -122,6 +122,9 @@ It defines DB schema using [Rails DSL](http://guides.rubyonrails.org/migrations.
|
|
122
122
|
* Fix unexpected warning when a foreign key is added on the primary key ([pull#307](https://github.com/winebarrel/ridgepole/pull/307))
|
123
123
|
* `>= 0.8.10`
|
124
124
|
* Raise an error if an InnoDB column has a foreign key but no index ([pull#310](https://github.com/winebarrel/ridgepole/pull/310))
|
125
|
+
* `>= 0.8.11`
|
126
|
+
* Fix FK index check support multiple PK ([pull#315](https://github.com/winebarrel/ridgepole/pull/315))
|
127
|
+
* Support t.reference() foreign_key option ([pull#316](https://github.com/winebarrel/ridgepole/pull/316))
|
125
128
|
</details>
|
126
129
|
|
127
130
|
## Installation
|
data/lib/ridgepole/dsl_parser.rb
CHANGED
@@ -37,7 +37,8 @@ module Ridgepole
|
|
37
37
|
attrs[:foreign_keys].each do |_, foreign_key_attrs|
|
38
38
|
fk_index = foreign_key_attrs[:options][:column] || "#{foreign_key_attrs[:to_table].singularize}_id"
|
39
39
|
next if attrs[:indices]&.any? { |_k, v| v[:column_name].first == fk_index }
|
40
|
-
|
40
|
+
# NOTE: For composite primary keys, the first column of the primary key is used as the foreign key index
|
41
|
+
next if Array(attrs[:options][:primary_key]).first == fk_index
|
41
42
|
|
42
43
|
raise "The column `#{fk_index}` of the table `#{table_name}` has a foreign key but no index. Although InnoDB creates an index automatically, please add one explicitly in order for ridgepole to manage it."
|
43
44
|
end
|
@@ -27,7 +27,7 @@ module Ridgepole
|
|
27
27
|
table_name = table_name.to_s
|
28
28
|
table_definition = TableDefinition.new(table_name, self)
|
29
29
|
|
30
|
-
options[:primary_key] = options[:primary_key].to_s if options[:primary_key]
|
30
|
+
options[:primary_key] = options[:primary_key].to_s if options[:primary_key].is_a?(Symbol)
|
31
31
|
if options[:id] && TableDefinition::ALIAS_TYPES.key?(options[:id])
|
32
32
|
type, type_default_opts = TableDefinition::ALIAS_TYPES[options[:id]]
|
33
33
|
options[:id] = type
|
@@ -131,6 +131,7 @@ module Ridgepole
|
|
131
131
|
polymorphic_options.merge!(options.slice(:null, :first, :after))
|
132
132
|
index_options = options.key?(:index) ? options.delete(:index) : true
|
133
133
|
type = options.delete(:type) || DEFAULT_PRIMARY_KEY_TYPE
|
134
|
+
foreign_key_options = options.delete(:foreign_key)
|
134
135
|
|
135
136
|
args.each do |col|
|
136
137
|
column("#{col}_id", type, options)
|
@@ -139,6 +140,12 @@ module Ridgepole
|
|
139
140
|
columns = polymorphic ? ["#{col}_type", "#{col}_id"] : ["#{col}_id"]
|
140
141
|
index(columns, index_options.is_a?(Hash) ? index_options : {})
|
141
142
|
end
|
143
|
+
if foreign_key_options # rubocop:disable Style/Next
|
144
|
+
fk_opts = foreign_key_options.is_a?(Hash) ? foreign_key_options.dup : {}
|
145
|
+
fk_opts.update(column: "#{col}_id") if col.to_s.singularize != col.to_s
|
146
|
+
to_table = fk_opts.delete(:to_table) || col
|
147
|
+
@base.add_foreign_key(@table_name, to_table, fk_opts)
|
148
|
+
end
|
142
149
|
end
|
143
150
|
end
|
144
151
|
alias belongs_to references
|
@@ -7,7 +7,7 @@ module Ridgepole
|
|
7
7
|
module AbstractMysqlAdapter
|
8
8
|
module UseAlterIndex
|
9
9
|
def add_index(table_name, column_name, options = {})
|
10
|
-
index_name, index_type, index_columns, index_options, _index_algorithm, index_using = add_index_options(table_name, column_name, options)
|
10
|
+
index_name, index_type, index_columns, index_options, _index_algorithm, index_using = add_index_options(table_name, column_name, **options)
|
11
11
|
|
12
12
|
# cannot specify index_algorithm
|
13
13
|
execute "ALTER TABLE #{quote_table_name(table_name)} ADD #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})#{index_options}"
|
data/lib/ridgepole/version.rb
CHANGED
data/ridgepole.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
20
|
spec.require_paths = ['lib']
|
21
21
|
|
22
|
-
spec.required_ruby_version = Gem::Requirement.new('>= 2.2.7')
|
22
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.2.7') # rubocop:disable Gemspec/RequiredRubyVersion
|
23
23
|
|
24
24
|
spec.add_dependency 'activerecord', '>= 5.0.1', '< 6.1'
|
25
25
|
spec.add_dependency 'diffy'
|
data/spec/erb_helper.rb
CHANGED
@@ -141,7 +141,7 @@ describe 'Ridgepole::Client#diff -> migrate' do
|
|
141
141
|
# v6.0.3 is the oldest version that doesn't produce any kwargs warnings with Ruby 2.7
|
142
142
|
if condition('< 6.0.3')
|
143
143
|
# https://github.com/jeremyevans/ruby-warning/blob/1.1.0/lib/warning.rb#L18
|
144
|
-
out = out.lines.grep_v(/: warning: (?:Using the last argument (?:for `.+' )?as keyword parameters is deprecated; maybe \*\* should be added to the call|Passing the keyword argument (?:for `.+' )?as the last hash parameter is deprecated|Splitting the last argument (?:for `.+' )?into positional and keyword parameters is deprecated|The called method (?:`.+' )?is defined here)\n\z/).join
|
144
|
+
out = out.lines.grep_v(/: warning: (?:Using the last argument (?:for `.+' )?as keyword parameters is deprecated; maybe \*\* should be added to the call|Passing the keyword argument (?:for `.+' )?as the last hash parameter is deprecated|Splitting the last argument (?:for `.+' )?into positional and keyword parameters is deprecated|The called method (?:`.+' )?is defined here)\n\z/).join
|
145
145
|
end
|
146
146
|
|
147
147
|
expect(out).to be_empty
|
@@ -239,3 +239,56 @@ describe 'Ridgepole::Client#diff -> migrate' do
|
|
239
239
|
}
|
240
240
|
end
|
241
241
|
end
|
242
|
+
|
243
|
+
context 'when create fk on the first primary key' do
|
244
|
+
let(:dsl) do
|
245
|
+
erbh(<<-ERB)
|
246
|
+
create_table "users", <%= i cond('>= 5.1',id: :integer) %>, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
|
247
|
+
end
|
248
|
+
|
249
|
+
create_table "employee", <%= i cond('>= 5.1',id: :integer) %>, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
|
250
|
+
end
|
251
|
+
|
252
|
+
create_table "icons", primary_key: ["user_id", "employee_id"], force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
|
253
|
+
t.integer "user_id", null: false
|
254
|
+
t.integer "employee_id", null: false
|
255
|
+
end
|
256
|
+
add_foreign_key "icons", "users", name: "fk_icons_users"
|
257
|
+
ERB
|
258
|
+
end
|
259
|
+
|
260
|
+
subject { client(dump_without_table_options: false) }
|
261
|
+
|
262
|
+
it {
|
263
|
+
expect(Ridgepole::Logger.instance).to_not receive(:warn)
|
264
|
+
subject.diff(dsl).migrate
|
265
|
+
|
266
|
+
expect(subject.diff(dsl).differ?).to be_falsey
|
267
|
+
}
|
268
|
+
end
|
269
|
+
|
270
|
+
context 'when create fk on the second primary key' do
|
271
|
+
let(:dsl) do
|
272
|
+
erbh(<<-ERB)
|
273
|
+
create_table "users", <%= i cond('>= 5.1',id: :integer) %>, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
|
274
|
+
end
|
275
|
+
|
276
|
+
create_table "employee", <%= i cond('>= 5.1',id: :integer) %>, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
|
277
|
+
end
|
278
|
+
|
279
|
+
create_table "icons", primary_key: ["user_id", "employee_id"], force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
|
280
|
+
t.integer "user_id", null: false
|
281
|
+
t.integer "employee_id", null: false
|
282
|
+
end
|
283
|
+
add_foreign_key "icons", "employees", name: "fk_icons_employees"
|
284
|
+
ERB
|
285
|
+
end
|
286
|
+
|
287
|
+
subject { client(dump_without_table_options: false) }
|
288
|
+
|
289
|
+
it {
|
290
|
+
expect do
|
291
|
+
subject.diff(dsl).migrate
|
292
|
+
end.to raise_error('The column `employee_id` of the table `icons` has a foreign key but no index. Although InnoDB creates an index automatically, please add one explicitly in order for ridgepole to manage it.')
|
293
|
+
}
|
294
|
+
end
|
@@ -310,4 +310,126 @@ describe 'Ridgepole::Client#diff -> migrate' do
|
|
310
310
|
expect(subject.dump).to match_ruby expected_dsl
|
311
311
|
}
|
312
312
|
end
|
313
|
+
|
314
|
+
context 'when use references with fk (no change)' do
|
315
|
+
let(:actual_dsl) do
|
316
|
+
erbh(<<-ERB)
|
317
|
+
create_table "products", force: :cascade do |t|
|
318
|
+
end
|
319
|
+
|
320
|
+
create_table "user", force: :cascade do |t|
|
321
|
+
end
|
322
|
+
|
323
|
+
create_table "employees", primary_key: "emp_no", force: :cascade do |t|
|
324
|
+
t.date "birth_date", null: false
|
325
|
+
t.string "first_name", limit: 14, null: false
|
326
|
+
t.string "last_name", limit: 16, null: false
|
327
|
+
t.string "gender", limit: 1, null: false
|
328
|
+
t.date "hire_date", null: false
|
329
|
+
t.<%= cond('>= 5.1','bigint', 'integer') %> "products_id"
|
330
|
+
t.<%= cond('>= 5.1','bigint', 'integer') %> "user_id"
|
331
|
+
t.index "products_id"
|
332
|
+
t.index "user_id"
|
333
|
+
end
|
334
|
+
|
335
|
+
add_foreign_key("employees", "products", **{:column=>"products_id"})
|
336
|
+
add_foreign_key("employees", "user")
|
337
|
+
ERB
|
338
|
+
end
|
339
|
+
|
340
|
+
let(:expected_dsl) do
|
341
|
+
erbh(<<-ERB)
|
342
|
+
create_table "products", force: :cascade do |t|
|
343
|
+
end
|
344
|
+
|
345
|
+
create_table "user", force: :cascade do |t|
|
346
|
+
end
|
347
|
+
|
348
|
+
create_table "employees", primary_key: "emp_no", force: :cascade do |t|
|
349
|
+
t.date "birth_date", null: false
|
350
|
+
t.string "first_name", limit: 14, null: false
|
351
|
+
t.string "last_name", limit: 16, null: false
|
352
|
+
t.string "gender", limit: 1, null: false
|
353
|
+
t.date "hire_date", null: false
|
354
|
+
t.references :products, :user, foreign_key: true
|
355
|
+
end
|
356
|
+
ERB
|
357
|
+
end
|
358
|
+
|
359
|
+
before { subject.diff(actual_dsl).migrate }
|
360
|
+
subject { client }
|
361
|
+
|
362
|
+
it {
|
363
|
+
delta = subject.diff(expected_dsl)
|
364
|
+
expect(delta.differ?).to be_falsey
|
365
|
+
}
|
366
|
+
end
|
367
|
+
|
368
|
+
context 'when use references with fk (change)' do
|
369
|
+
let(:actual_dsl) do
|
370
|
+
erbh(<<-ERB)
|
371
|
+
create_table "employees", primary_key: "emp_no", force: :cascade do |t|
|
372
|
+
t.date "birth_date", null: false
|
373
|
+
t.string "first_name", limit: 14, null: false
|
374
|
+
t.string "last_name", limit: 16, null: false
|
375
|
+
t.string "gender", limit: 1, null: false
|
376
|
+
t.date "hire_date", null: false
|
377
|
+
end
|
378
|
+
create_table "products", force: :cascade do |t|
|
379
|
+
end
|
380
|
+
create_table "user", force: :cascade do |t|
|
381
|
+
end
|
382
|
+
ERB
|
383
|
+
end
|
384
|
+
|
385
|
+
let(:dsl) do
|
386
|
+
erbh(<<-ERB)
|
387
|
+
create_table "employees", primary_key: "emp_no", force: :cascade do |t|
|
388
|
+
t.date "birth_date", null: false
|
389
|
+
t.string "first_name", limit: 14, null: false
|
390
|
+
t.string "last_name", limit: 16, null: false
|
391
|
+
t.string "gender", limit: 1, null: false
|
392
|
+
t.date "hire_date", null: false
|
393
|
+
t.references :products, :user, foreign_key: true
|
394
|
+
end
|
395
|
+
create_table "products", force: :cascade do |t|
|
396
|
+
end
|
397
|
+
create_table "user", force: :cascade do |t|
|
398
|
+
end
|
399
|
+
ERB
|
400
|
+
end
|
401
|
+
|
402
|
+
let(:expected_dsl) do
|
403
|
+
erbh(<<-ERB)
|
404
|
+
create_table "employees", primary_key: "emp_no", force: :cascade do |t|
|
405
|
+
t.date "birth_date", null: false
|
406
|
+
t.string "first_name", limit: 14, null: false
|
407
|
+
t.string "last_name", limit: 16, null: false
|
408
|
+
t.string "gender", limit: 1, null: false
|
409
|
+
t.date "hire_date", null: false
|
410
|
+
t.<%= cond('>= 5.1','bigint', 'integer') %> "products_id"
|
411
|
+
t.<%= cond('>= 5.1','bigint', 'integer') %> "user_id"
|
412
|
+
t.index ["products_id"], name: "index_employees_on_products_id", <%= i cond(5.0, using: :btree) %>
|
413
|
+
t.index ["user_id"], name: "index_employees_on_user_id", <%= i cond(5.0, using: :btree) %>
|
414
|
+
end
|
415
|
+
create_table "products", force: :cascade do |t|
|
416
|
+
end
|
417
|
+
create_table "user", force: :cascade do |t|
|
418
|
+
end
|
419
|
+
add_foreign_key("employees", "products", column: "products_id")
|
420
|
+
add_foreign_key("employees", "user")
|
421
|
+
ERB
|
422
|
+
end
|
423
|
+
|
424
|
+
before { subject.diff(actual_dsl).migrate }
|
425
|
+
subject { client }
|
426
|
+
|
427
|
+
it {
|
428
|
+
delta = subject.diff(dsl)
|
429
|
+
expect(delta.differ?).to be_truthy
|
430
|
+
expect(subject.dump).to match_ruby actual_dsl
|
431
|
+
delta.migrate
|
432
|
+
expect(subject.dump).to match_ruby expected_dsl
|
433
|
+
}
|
434
|
+
end
|
313
435
|
end
|
data/spec/spec_condition.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -25,10 +25,11 @@ require 'erb_helper'
|
|
25
25
|
|
26
26
|
RSpec.configure do |config|
|
27
27
|
config.before(:all) do
|
28
|
-
if condition(:debug)
|
28
|
+
if condition(:debug) || condition(:verbose)
|
29
29
|
ActiveRecord::Migration.verbose = true
|
30
30
|
logger = Ridgepole::Logger.instance
|
31
31
|
logger.level = ::Logger::DEBUG
|
32
|
+
logger.verbose = condition(:verbose)
|
32
33
|
ActiveRecord::Base.logger = logger
|
33
34
|
else
|
34
35
|
ActiveRecord::Migration.verbose = false
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ridgepole
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Genki Sugawara
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -429,7 +429,7 @@ homepage: https://github.com/winebarrel/ridgepole
|
|
429
429
|
licenses:
|
430
430
|
- MIT
|
431
431
|
metadata: {}
|
432
|
-
post_install_message:
|
432
|
+
post_install_message:
|
433
433
|
rdoc_options: []
|
434
434
|
require_paths:
|
435
435
|
- lib
|
@@ -444,8 +444,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
444
444
|
- !ruby/object:Gem::Version
|
445
445
|
version: '0'
|
446
446
|
requirements: []
|
447
|
-
rubygems_version: 3.
|
448
|
-
signing_key:
|
447
|
+
rubygems_version: 3.1.2
|
448
|
+
signing_key:
|
449
449
|
specification_version: 4
|
450
450
|
summary: Ridgepole is a tool to manage DB schema.
|
451
451
|
test_files:
|