ridgepole 3.1.3 → 3.1.5

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: 5f54f0a59342af5d5d5bc4a1bce81f963a5f85b8b6da78702dbb03db59488dfe
4
- data.tar.gz: d163b0a5ef7ff03125b83d40b977e6c6f7097f7a6286a4c7d1ae165e19638126
3
+ metadata.gz: b6de4765b254e55e4087b4fe7d99a9c23493e0c54b0a7c7e957b88488fa234d2
4
+ data.tar.gz: 6d05534c60e9f9f0967179520d8ecd83bee84b96cbe1e80cd4336327f7cb8c37
5
5
  SHA512:
6
- metadata.gz: 1092d39833a655561847f2e04a98056311b63249baabf246bfc25aacd23003a6b8573e17ba835afe3b75bd1f88e6c903dc8f8d7aa471c3c9a69a7331f55acaaf
7
- data.tar.gz: 2c6ceafe3191a18f0558ab0d7acf74b6133c5389a439602d1159cbdc47980cc8727ed21dfef11e55b3fc026312e32b6ceaf4475dbe36be5df6fe2a0d109bb877
6
+ metadata.gz: 1bb9273027a3b3d74c7c18faf25ba4b47033a44b98b12b1de80e04cd521aeb994f45168e97603b56c87dac6839990322eb8b2131e438320772983b9636a8695e
7
+ data.tar.gz: 49099509a1f3d8e5ae98fb7fe442e942ba7c7def24cf8a065e7c0d8838826e8ba4ec6394e4f9a5fa12cb906f2e850cb1a89e10496bbd07801ba746bf429f6389
data/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  ## 3.0
4
4
 
5
+ ### 3.1.5 (2026/03/21)
6
+
7
+ - Fix for renaming references column. [pull#652](https://github.com/ridgepole/ridgepole/pull/652)
8
+ - Fix for creating table with non-PK auto_increment column. [pull#650](https://github.com/ridgepole/ridgepole/pull/650)
9
+
10
+ ### 3.1.4 (2026/03/20)
11
+
12
+ - Fix for errors when changing generated columns. [pull#642](https://github.com/ridgepole/ridgepole/pull/642) [pull#646](https://github.com/ridgepole/ridgepole/pull/646)
13
+ - Fix for changes to `create_table` in ActiveRecord 8.2. [pull#645](https://github.com/ridgepole/ridgepole/pull/645)
14
+
5
15
  ### 3.1.3 (2026/01/29)
6
16
 
7
17
  - Show `COMMENT` SQL in dry-run. [pull#632](https://github.com/ridgepole/ridgepole/pull/632)
data/README.md CHANGED
@@ -412,9 +412,9 @@ see https://github.com/ridgepole/ridgepole/issues/568
412
412
  docker compose up -d
413
413
  bundle install
414
414
  bundle exec appraisal install
415
- bundle exec appraisal activerecord-8.2 rake
416
- # POSTGRESQL=1 bundle exec appraisal activerecord-8.2 rake
417
- # MYSQL80=1 bundle exec appraisal activerecord-8.2 rake
415
+ bundle exec appraisal activerecord-8.1 rake
416
+ # POSTGRESQL=1 bundle exec appraisal activerecord-8.1 rake
417
+ # MYSQL80=1 bundle exec appraisal activerecord-8.1 rake
418
418
  ```
419
419
 
420
420
  > [!note]
@@ -10,7 +10,7 @@ module Ridgepole
10
10
  # XXX: If the required processing in class method?
11
11
  @options[:index_removed_drop_column] = true if !@options.key?(:index_removed_drop_column) && (Ridgepole::DefaultsLimit.adapter == :postgresql)
12
12
 
13
- Ridgepole::ExecuteExpander.expand_execute(ActiveRecord::Base.connection)
13
+ Ridgepole::ExecuteExpander.expand_execute(ActiveRecord::Base.connection, @options)
14
14
  @dumper = Ridgepole::Dumper.new(@options)
15
15
  @parser = Ridgepole::DSLParser.new(@options)
16
16
  @diff = Ridgepole::Diff.new(@options)
@@ -74,7 +74,7 @@ module Ridgepole
74
74
  ActiveRecord::Migration.disable_logging = true
75
75
  buf = StringIO.new
76
76
 
77
- callback = proc do |sql, _name|
77
+ callback = proc do |sql|
78
78
  buf.puts sql if sql =~ /\A(CREATE|ALTER|DROP|RENAME|COMMENT)\b/i
79
79
  end
80
80
 
@@ -243,10 +243,18 @@ create_table(#{table_name.inspect}, #{inspect_options_include_default_proc(optio
243
243
  RUBY
244
244
  end
245
245
 
246
- if @options[:create_table_with_index] && !indices.empty?
247
- indices.each do |index_name, index_attrs|
248
- append_add_index(table_name, index_name, index_attrs, buf, true)
249
- end
246
+ # Partition indices: indices referencing auto_increment columns must be
247
+ # inside CREATE TABLE on MySQL to avoid "must be defined as a key" error.
248
+ # cf. https://github.com/ridgepole/ridgepole/issues/494
249
+ if @options[:create_table_with_index]
250
+ indices_in_create = indices
251
+ indices_after_create = {}
252
+ else
253
+ indices_in_create, indices_after_create = partition_indices_for_create(definition, indices)
254
+ end
255
+
256
+ indices_in_create.each do |index_name, index_attrs|
257
+ append_add_index(table_name, index_name, index_attrs, buf, true)
250
258
  end
251
259
 
252
260
  unless (check_constraints = attrs[:check_constraints] || {}).empty?
@@ -271,9 +279,9 @@ create_table(#{table_name.inspect}, #{inspect_options_include_default_proc(optio
271
279
  end
272
280
  RUBY
273
281
 
274
- if !@options[:create_table_with_index] && !indices.empty?
282
+ unless indices_after_create.empty?
275
283
  append_change_table(table_name, buf) do
276
- indices.each do |index_name, index_attrs|
284
+ indices_after_create.each do |index_name, index_attrs|
277
285
  append_add_index(table_name, index_name, index_attrs, buf)
278
286
  end
279
287
  end
@@ -289,6 +297,30 @@ end
289
297
  post_buf_for_fk.puts
290
298
  end
291
299
 
300
+ def partition_indices_for_create(definition, indices)
301
+ return [{}, indices] unless Ridgepole::ConnectionAdapters.mysql?
302
+
303
+ auto_increment_columns = definition.select do |_col_name, col_attrs|
304
+ col_attrs.dig(:options, :auto_increment)
305
+ end.keys
306
+
307
+ return [{}, indices] if auto_increment_columns.empty?
308
+
309
+ in_create = {}
310
+ after_create = {}
311
+
312
+ indices.each do |idx_name, idx_attrs|
313
+ columns = Array(idx_attrs[:column_name])
314
+ if (columns & auto_increment_columns).any?
315
+ in_create[idx_name] = idx_attrs
316
+ else
317
+ after_create[idx_name] = idx_attrs
318
+ end
319
+ end
320
+
321
+ [in_create, after_create]
322
+ end
323
+
292
324
  def append_rename_table(to_table_name, from_table_name, buf)
293
325
  buf.puts(<<-RUBY)
294
326
  rename_table(#{from_table_name.inspect}, #{to_table_name.inspect})
@@ -446,6 +478,13 @@ rename_column(#{table_name.inspect}, #{from_column_name.inspect}, #{to_column_na
446
478
  # Fix for https://github.com/rails/rails/commit/7f0567b43b73b1bd1a16bfac9cd32fcbf1321b51
447
479
  if Ridgepole::ConnectionAdapters.mysql?
448
480
  options[:comment] = nil unless options.key?(:comment)
481
+
482
+ # Generated/virtual columns cannot have DEFAULT values in MySQL.
483
+ # cf. https://github.com/ridgepole/ridgepole/issues/482
484
+ if type == :virtual
485
+ options.delete(:default)
486
+ options.delete(:unsigned)
487
+ end
449
488
  end
450
489
 
451
490
  if @options[:bulk_change]
@@ -103,6 +103,7 @@ module Ridgepole
103
103
 
104
104
  scan_options_change(table_name, from[:options], to[:options], table_delta)
105
105
  scan_definition_change(from[:definition], to[:definition], from[:indices], table_name, from[:options], table_delta)
106
+ apply_column_renames_to_indices(from[:indices], table_delta.dig(:definition, :rename))
106
107
  scan_indices_change(from[:indices], to[:indices], to[:definition], table_delta, from[:options], to[:options])
107
108
  scan_foreign_keys_change(from[:foreign_keys], to[:foreign_keys], table_delta, @options)
108
109
  scan_check_constraints_change(from[:check_constraints], to[:check_constraints], table_delta)
@@ -342,6 +343,19 @@ module Ridgepole
342
343
  end
343
344
  end
344
345
 
346
+ def apply_column_renames_to_indices(indices, renames)
347
+ return unless indices && renames
348
+
349
+ # renames: { new_column_name => old_column_name }
350
+ rename_map = renames.invert # { old_column_name => new_column_name }
351
+
352
+ indices.each_value do |attrs|
353
+ next unless attrs[:column_name].is_a?(Array)
354
+
355
+ attrs[:column_name] = attrs[:column_name].map { |col| rename_map[col] || col }
356
+ end
357
+ end
358
+
345
359
  def scan_indices_change(from, to, to_columns, table_delta, _from_table_options, to_table_options)
346
360
  from = (from || {}).dup
347
361
  to = (to || {}).dup
@@ -410,15 +424,17 @@ module Ridgepole
410
424
 
411
425
  def normalize_column_options!(attrs, primary_key = false)
412
426
  opts = attrs[:options]
413
- opts[:null] = true if !opts.key?(:null) && !primary_key
427
+ opts[:null] = true if !opts.key?(:null) && !primary_key && attrs[:type] != :virtual
414
428
  default_limit = Ridgepole::DefaultsLimit.default_limit(attrs[:type], @options)
415
429
  opts.delete(:limit) if opts[:limit] == default_limit
416
430
 
417
431
  # XXX: MySQL only?
418
- opts[:default] = nil if !opts.key?(:default) && !primary_key
432
+ # Generated/virtual columns cannot have DEFAULT values in MySQL.
433
+ # cf. https://github.com/ridgepole/ridgepole/issues/482
434
+ opts[:default] = nil if !opts.key?(:default) && !primary_key && attrs[:type] != :virtual
419
435
 
420
436
  if Ridgepole::ConnectionAdapters.mysql?
421
- opts[:unsigned] = false unless opts.key?(:unsigned)
437
+ opts[:unsigned] = false if !opts.key?(:unsigned) && attrs[:type] != :virtual
422
438
 
423
439
  if attrs[:type] == :integer && opts[:limit]
424
440
  min = Ridgepole::DefaultsLimit.default_limit(:integer, @options)
@@ -13,19 +13,24 @@ module Ridgepole
13
13
  end
14
14
 
15
15
  module ConnectionAdapterExt
16
- def execute(*args)
17
- sql = args.fetch(0)
18
- name = args[1]
19
-
16
+ def execute_expander_internal_execute(sql, &block)
17
+ # Generated/virtual columns cannot have DEFAULT values in MySQL.
18
+ # Rails' change_column always adds DEFAULT from the existing column,
19
+ # so we strip it from the SQL for virtual columns.
20
+ # cf. https://github.com/ridgepole/ridgepole/issues/482
21
+ if Ridgepole::ConnectionAdapters.mysql? && !Ridgepole::ExecuteExpander.options[:bulk_change]
22
+ # NOTE: bulk_change does not support changing MySQL generated columns with `DEFAULT NULL`.
23
+ sql = sql.sub(/\bDEFAULT\s+NULL\z/i, '') if /\AALTER\s+TABLE\b/i.match?(sql) && /\bAS\s*\(/i.match?(sql) && /\bDEFAULT\s+NULL\z/i.match?(sql)
24
+ end
20
25
  if Ridgepole::ExecuteExpander.noop
21
26
  if (callback = Ridgepole::ExecuteExpander.callback)
22
27
  sql = append_alter_extra(sql)
23
- callback.call(sql, name)
28
+ callback.call(sql)
24
29
  end
25
30
 
26
31
  if /\A(SELECT|SHOW)\b/i.match?(sql)
27
32
  begin
28
- super(sql, name)
33
+ block.call(sql)
29
34
  rescue StandardError
30
35
  Stub.new
31
36
  end
@@ -34,7 +39,7 @@ module Ridgepole
34
39
  end
35
40
  elsif Ridgepole::ExecuteExpander.use_script
36
41
  if /\A(SELECT|SHOW)\b/i.match?(sql)
37
- super(sql, name)
42
+ block.call(sql)
38
43
  else
39
44
  sql = append_alter_extra(sql)
40
45
  Ridgepole::ExecuteExpander.sql_executer.execute(sql)
@@ -42,10 +47,28 @@ module Ridgepole
42
47
  end
43
48
  else
44
49
  sql = append_alter_extra(sql)
50
+ block.call(sql)
51
+ end
52
+ end
53
+
54
+ def execute(*args)
55
+ name = args[1]
56
+ execute_expander_internal_execute(args.fetch(0)) do |sql|
45
57
  super(sql, name)
46
58
  end
47
59
  end
48
60
 
61
+ def execute_batch(statements, name = nil, **kwargs)
62
+ new_statements = []
63
+ statements.each do |statement|
64
+ execute_expander_internal_execute(statement) do |sql|
65
+ new_statements << sql
66
+ end
67
+ end
68
+ super(new_statements, name, **kwargs) unless new_statements.empty?
69
+ statements
70
+ end
71
+
49
72
  private
50
73
 
51
74
  def append_alter_extra(sql)
@@ -69,6 +92,7 @@ module Ridgepole
69
92
  cattr_accessor :use_script, instance_writer: false, instance_reader: false
70
93
  cattr_accessor :sql_executer, instance_writer: false, instance_reader: false
71
94
  cattr_accessor :alter_extra, instance_writer: false, instance_reader: false
95
+ cattr_accessor :options, instance_writer: false, instance_reader: false
72
96
 
73
97
  class << self
74
98
  def without_operation(callback = nil)
@@ -96,9 +120,11 @@ module Ridgepole
96
120
  self.alter_extra = nil
97
121
  end
98
122
 
99
- def expand_execute(connection)
123
+ def expand_execute(connection, options)
100
124
  return if connection.is_a?(ConnectionAdapterExt)
101
125
 
126
+ self.options = options
127
+
102
128
  connection.class_eval do
103
129
  prepend ConnectionAdapterExt
104
130
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ridgepole
4
- VERSION = '3.1.3'
4
+ VERSION = '3.1.5'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ridgepole
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.3
4
+ version: 3.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Genki Sugawara
@@ -245,14 +245,14 @@ dependencies:
245
245
  requirements:
246
246
  - - '='
247
247
  - !ruby/object:Gem::Version
248
- version: 1.82.1
248
+ version: 1.85.1
249
249
  type: :development
250
250
  prerelease: false
251
251
  version_requirements: !ruby/object:Gem::Requirement
252
252
  requirements:
253
253
  - - '='
254
254
  - !ruby/object:Gem::Version
255
- version: 1.82.1
255
+ version: 1.85.1
256
256
  - !ruby/object:Gem::Dependency
257
257
  name: rubocop-rake
258
258
  requirement: !ruby/object:Gem::Requirement