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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6f850327d50c5d732987209c8c8eb5c9db3090e1b638f2ee9dbc8ced0959b128
4
- data.tar.gz: 242e925ebc5c1a94d0c68e605e894a55efab238f1184b67d1a6a56f4aee51078
3
+ metadata.gz: 367dff4faf9fd7e94588cdefe290cf13953cf82b9dc5110e91cfd5d4ee2507a3
4
+ data.tar.gz: 20ad65390cd7b12fe97e8fbae409aa5bc0d86a6c73c79a9916bfc55f46f03cb6
5
5
  SHA512:
6
- metadata.gz: 0451a8c71155ff9fd991045e04973cdf063c405dc1013c63883db20ce11bad93ce4f7cdd0533d5ae12f4a9c35bbf03e18e04a6487ad217baf614a090837095d4
7
- data.tar.gz: f4bb253e35a0f7904a0b17effd29a5e388449d4a295282f9f1652f1dd11f6d8a9c1df8dbd176efcf884cda5e15e15bf80db61b69bfd7f702ee43de2e0b70a186
6
+ metadata.gz: 94039eb4e75e2f0b218275ffec9b8a1b4c28ae5b9c93ad64b584793acbabc1ece9eb8ddde4e6d3097ffc6a9346ef36a6318334048d99c8e85050e0b9ef3088bd
7
+ data.tar.gz: 5e4837104ea5b6b69e42fdcc82e29b71a33835ce8371b959c16f3c00b014047a88b3c01ecba74ab8d6e591fd3357d15019a1dc41c425ff4c10b49fcec6bbdc48
@@ -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
- Lint/MixedRegexpCaptureTypes:
51
- Enabled: true
52
- Lint/RaiseException:
53
- Enabled: true
54
- Lint/StructNewOverride:
55
- Enabled: true
56
- Style/AccessorGrouping:
57
- Enabled: true
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
@@ -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
- next if attrs[:options][:primary_key] == fk_index
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]&.is_a?(Symbol)
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}"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ridgepole
4
- VERSION = '0.8.10'
4
+ VERSION = '0.8.11'
5
5
  end
@@ -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'
@@ -18,9 +18,9 @@ ERBh.define_method(:cond) do |conds, m, e = nil|
18
18
  m
19
19
  else
20
20
  e || (begin
21
- m.class.new
22
- rescue StandardError
23
- nil
24
- end)
21
+ m.class.new
22
+ rescue StandardError
23
+ nil
24
+ end)
25
25
  end
26
26
  end
@@ -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
@@ -19,6 +19,10 @@ module SpecCondition
19
19
  def debug?
20
20
  ENV['DEBUG'] == '1'
21
21
  end
22
+
23
+ def verbose?
24
+ ENV['VERBOSE'] == '1'
25
+ end
22
26
  end
23
27
 
24
28
  def check_version_or_cond(version_or_cond)
@@ -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.10
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-08-16 00:00:00.000000000 Z
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.0.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: