ridgepole 0.8.10 → 0.8.11
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|