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 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: