ridgepole 1.2.1 → 2.0.0.beta

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: f90fd48ae734b53cd516ac3006e2a3d0b2582c1ed3a2ed1eacccc8884a382bf0
4
- data.tar.gz: 926c56a91a6e58a64fbbb46f44ca640983a9285e509ec5b3295aaa5b7d2317c3
3
+ metadata.gz: f259bb56c8c8193c060dd6b3e14b9c90fbe8e5105046ebbefcd9e140656fd176
4
+ data.tar.gz: 6b5d498ac6dfde45c7a2306942baf0bdef2dba66d5a3073e7fe886d6092e4cdf
5
5
  SHA512:
6
- metadata.gz: d00a0d85d16b360912b06da4b26185cea444dc7de4f96cb388881f5859e8592852c3c2fba6797e68436aa4ee000bfd705e0edaea76fafb7333c1b9d81d38001b
7
- data.tar.gz: b2a4beae21348b43a401af11448d922dbb1e40c8149ea0d7369d4bc4ff14fc10a6f468e1c2d660ad7fd31731d9661feca62c3a04165f8a9fd098c69b872a285d
6
+ metadata.gz: 3ed96d3b0f2d451544d0154a1840342b4bd873fcd416d9c65f17181d22e1742ea39deb17abc03e52002a204e80943390975087ff46992501283dc658e71a9253
7
+ data.tar.gz: eb533bb2e3613b82fc3ca2e11f1d1b6d4a17e8238030acaba0f679b31b11798d7accd9347d4c1e575cbf09da3de95851244360735a024ea77fa904962aab13d0
data/Appraisals CHANGED
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- appraise 'activerecord-6.0' do
4
- gem 'activerecord', '~> 6.0.6'
5
- end
6
-
7
3
  appraise 'activerecord-6.1' do
8
4
  gem 'activerecord', '~> 6.1.7'
9
5
  end
@@ -11,3 +7,7 @@ end
11
7
  appraise 'activerecord-7.0' do
12
8
  gem 'activerecord', '~> 7.0.4'
13
9
  end
10
+
11
+ appraise 'activerecord-7.1' do
12
+ gem 'activerecord', '~> 7.1.0'
13
+ end
data/CHANGELOG.md CHANGED
@@ -1,10 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.0
4
+
5
+ ### 2.0.0.beta (2023/10/22)
6
+
7
+ * Support Rails 7.1 [pull#441](https://github.com/ridgepole/ridgepole/pull/441)
8
+ * Drop Rails 6.0 support [pull#440](https://github.com/ridgepole/ridgepole/pull/440)
9
+
3
10
  ## 1.2
4
11
 
5
12
  ### 1.2.1 (2023/07/29)
6
13
 
7
- * Support `create_enum` [pull#405](https://github.com/ridgepole/ridgepole/pull/405)
14
+ * Support `t.enum` [pull#405](https://github.com/ridgepole/ridgepole/pull/405)
8
15
  * Fix timestamps with index behavior [pull#428](https://github.com/ridgepole/ridgepole/pull/428)
9
16
  * Fix broken `DEFAULT CURRENT_TIMESTAMP` spec [pull#420](https://github.com/ridgepole/ridgepole/pull/420)
10
17
  * Add Ruby 3.2 to CI matrix [pull#419](https://github.com/ridgepole/ridgepole/pull/419)
data/README.md CHANGED
@@ -11,6 +11,8 @@ It defines DB schema using [Rails DSL](http://guides.rubyonrails.org/migrations.
11
11
 
12
12
  **Notice**
13
13
 
14
+ * Support Rails 7.1 ridgepole v2.0.0.
15
+ * Drop support AcriveRecord 6.0 in ridgepole v2.0.0.
14
16
  * Drop support ActiveRecord 5.x in ridgepole v1.2.0.
15
17
  * Partitioning is no longer supported in ridgepole v1.1.0.
16
18
  * ActiveRecord 7.x has some incompatible changes. If you get unintended differences in `datetime` columns consider changing `precision`:
@@ -312,7 +314,7 @@ end
312
314
  ```
313
315
 
314
316
  ```sh
315
- $ ridgepole -a -c database.yml --check-relation-type bigint # default primary key type (e.g. `<5.1`: integer, `>=5.1`: bigint for MySQL)
317
+ $ ridgepole -a -c database.yml --check-relation-type bigint # default primary key type (e.g. bigint for MySQL)
316
318
  Apply `Schemafile`
317
319
  ...
318
320
  [WARNING] Relation column type is different.
@@ -2,6 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", "~> 7.0.4"
5
+ gem "activerecord", "~> 7.0.7"
6
6
 
7
7
  gemspec path: "../"
@@ -2,6 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", "~> 6.0.6"
5
+ gem "activerecord", "~> 7.1.0"
6
6
 
7
7
  gemspec path: "../"
@@ -251,6 +251,18 @@ create_table(#{table_name.inspect}, #{inspect_options_include_default_proc(optio
251
251
  end
252
252
  end
253
253
 
254
+ unless (exclusion_constraints = attrs[:exclusion_constraints] || {}).empty?
255
+ exclusion_constraints.each do |_, exclusion_constraint_attrs|
256
+ append_add_exclusion_constraint(table_name, exclusion_constraint_attrs, buf, true)
257
+ end
258
+ end
259
+
260
+ unless (unique_constraints = attrs[:unique_constraints] || {}).empty?
261
+ unique_constraints.each do |_, unique_constraint_attrs|
262
+ append_add_unique_constraint(table_name, unique_constraint_attrs, buf, true)
263
+ end
264
+ end
265
+
254
266
  buf.puts(<<-RUBY)
255
267
  end
256
268
  RUBY
@@ -299,7 +311,7 @@ execute "ALTER TABLE #{ActiveRecord::Base.connection.quote_table_name(table_name
299
311
  end
300
312
 
301
313
  def append_change_table_raw_options(table_name, raw_table_options, table_charset, table_collation, buf)
302
- if raw_table_options.blank? && ActiveRecord.gem_version >= Gem::Version.new('6.1.0')
314
+ if raw_table_options.blank?
303
315
  # Implicit engine is InnoDB in 6.1.0
304
316
  # related: https://github.com/rails/rails/pull/39365/files#diff-868f1dccfcbed26a288bf9f3fd8a39c863a4413ab0075e12b6805d9798f556d1R441
305
317
  raw_table_options = +'ENGINE=InnoDB'
@@ -322,6 +334,8 @@ execute "ALTER TABLE #{ActiveRecord::Base.connection.quote_table_name(table_name
322
334
  indices = attrs[:indices] || {}
323
335
  foreign_keys = attrs[:foreign_keys] || {}
324
336
  check_constraints = attrs[:check_constraints] || {}
337
+ exclusion_constraints = attrs[:exclusion_constraints] || {}
338
+ unique_constraints = attrs[:unique_constraints] || {}
325
339
  table_options = attrs[:table_options]
326
340
  table_charset = attrs[:table_charset]
327
341
  table_collation = attrs[:table_collation]
@@ -338,6 +352,8 @@ execute "ALTER TABLE #{ActiveRecord::Base.connection.quote_table_name(table_name
338
352
 
339
353
  append_change_foreign_keys(table_name, foreign_keys, pre_buf_for_fk, post_buf_for_fk, @options) unless foreign_keys.empty?
340
354
  append_change_check_constraints(table_name, check_constraints, buf) unless check_constraints.empty?
355
+ append_change_exclusion_constraints(table_name, exclusion_constraints, buf) unless exclusion_constraints.empty?
356
+ append_change_unique_constraints(table_name, unique_constraints, buf) unless unique_constraints.empty?
341
357
 
342
358
  if table_options || table_charset || table_collation
343
359
  append_change_table_raw_options(table_name, table_options, table_charset, table_collation,
@@ -553,6 +569,74 @@ remove_check_constraint(#{table_name.inspect}, #{expression.inspect}, **#{attrs_
553
569
  RUBY
554
570
  end
555
571
 
572
+ def append_change_exclusion_constraints(table_name, delta, buf)
573
+ (delta[:delete] || {}).each do |_, attrs|
574
+ append_remove_exclusion_constraint(table_name, attrs, buf)
575
+ end
576
+
577
+ (delta[:add] || {}).each do |_, attrs|
578
+ append_add_exclusion_constraint(table_name, attrs, buf)
579
+ end
580
+ end
581
+
582
+ def append_add_exclusion_constraint(table_name, attrs, buf, force_bulk_change = false)
583
+ expression = attrs.fetch(:expression)
584
+ attrs_options = attrs[:options] || {}
585
+
586
+ if force_bulk_change
587
+ buf.puts(<<-RUBY)
588
+ t.exclusion_constraint(#{expression.inspect}, **#{attrs_options.inspect})
589
+ RUBY
590
+ else
591
+ buf.puts(<<-RUBY)
592
+ add_exclusion_constraint(#{table_name.inspect}, #{expression.inspect}, **#{attrs_options.inspect})
593
+ RUBY
594
+ end
595
+ end
596
+
597
+ def append_remove_exclusion_constraint(table_name, attrs, buf)
598
+ expression = attrs.fetch(:expression)
599
+ attrs_options = attrs[:options] || {}
600
+
601
+ buf.puts(<<-RUBY)
602
+ remove_exclusion_constraint(#{table_name.inspect}, #{expression.inspect}, **#{attrs_options.inspect})
603
+ RUBY
604
+ end
605
+
606
+ def append_change_unique_constraints(table_name, delta, buf)
607
+ (delta[:delete] || {}).each do |_, attrs|
608
+ append_remove_unique_constraint(table_name, attrs, buf)
609
+ end
610
+
611
+ (delta[:add] || {}).each do |_, attrs|
612
+ append_add_unique_constraint(table_name, attrs, buf)
613
+ end
614
+ end
615
+
616
+ def append_add_unique_constraint(table_name, attrs, buf, force_bulk_change = false)
617
+ column_name = attrs.fetch(:column_name)
618
+ attrs_options = attrs[:options] || {}
619
+
620
+ if force_bulk_change
621
+ buf.puts(<<-RUBY)
622
+ t.unique_constraint(#{column_name.inspect}, **#{attrs_options.inspect})
623
+ RUBY
624
+ else
625
+ buf.puts(<<-RUBY)
626
+ add_unique_constraint(#{table_name.inspect}, #{column_name.inspect}, **#{attrs_options.inspect})
627
+ RUBY
628
+ end
629
+ end
630
+
631
+ def append_remove_unique_constraint(table_name, attrs, buf)
632
+ column_name = attrs.fetch(:column_name)
633
+ attrs_options = attrs[:options] || {}
634
+
635
+ buf.puts(<<-RUBY)
636
+ remove_unique_constraint(#{table_name.inspect}, #{column_name.inspect}, **#{attrs_options.inspect})
637
+ RUBY
638
+ end
639
+
556
640
  def delta_execute
557
641
  @delta[:execute] || []
558
642
  end
@@ -102,6 +102,8 @@ module Ridgepole
102
102
  scan_indices_change(from[:indices], to[:indices], to[:definition], table_delta, from[:options], to[:options])
103
103
  scan_foreign_keys_change(from[:foreign_keys], to[:foreign_keys], table_delta, @options)
104
104
  scan_check_constraints_change(from[:check_constraints], to[:check_constraints], table_delta)
105
+ scan_exclusion_constraints_change(from[:exclusion_constraints], to[:exclusion_constraints], table_delta)
106
+ scan_unique_constraints_change(from[:unique_constraints], to[:unique_constraints], table_delta)
105
107
 
106
108
  unless table_delta.empty?
107
109
  delta[:change] ||= {}
@@ -505,6 +507,70 @@ module Ridgepole
505
507
  table_delta[:check_constraints] = check_constraints_delta unless check_constraints_delta.empty?
506
508
  end
507
509
 
510
+ def scan_exclusion_constraints_change(from, to, table_delta)
511
+ from = (from || {}).dup
512
+ to = (to || {}).dup
513
+ exclusion_constraints_delta = {}
514
+
515
+ to.each do |name, to_attrs|
516
+ from_attrs = from.delete(name)
517
+
518
+ if from_attrs
519
+ if from_attrs != to_attrs
520
+ exclusion_constraints_delta[:add] ||= {}
521
+ exclusion_constraints_delta[:add][name] = to_attrs
522
+
523
+ exclusion_constraints_delta[:delete] ||= {}
524
+ exclusion_constraints_delta[:delete][name] = from_attrs
525
+ end
526
+ else
527
+ exclusion_constraints_delta[:add] ||= {}
528
+ exclusion_constraints_delta[:add][name] = to_attrs
529
+ end
530
+ end
531
+
532
+ unless @options[:merge]
533
+ from.each do |name, from_attrs|
534
+ exclusion_constraints_delta[:delete] ||= {}
535
+ exclusion_constraints_delta[:delete][name] = from_attrs
536
+ end
537
+ end
538
+
539
+ table_delta[:exclusion_constraints] = exclusion_constraints_delta unless exclusion_constraints_delta.empty?
540
+ end
541
+
542
+ def scan_unique_constraints_change(from, to, table_delta)
543
+ from = (from || {}).dup
544
+ to = (to || {}).dup
545
+ unique_constraints_delta = {}
546
+
547
+ to.each do |name, to_attrs|
548
+ from_attrs = from.delete(name)
549
+
550
+ if from_attrs
551
+ if from_attrs != to_attrs
552
+ unique_constraints_delta[:add] ||= {}
553
+ unique_constraints_delta[:add][name] = to_attrs
554
+
555
+ unique_constraints_delta[:delete] ||= {}
556
+ unique_constraints_delta[:delete][name] = from_attrs
557
+ end
558
+ else
559
+ unique_constraints_delta[:add] ||= {}
560
+ unique_constraints_delta[:add][name] = to_attrs
561
+ end
562
+ end
563
+
564
+ unless @options[:merge]
565
+ from.each do |name, from_attrs|
566
+ unique_constraints_delta[:delete] ||= {}
567
+ unique_constraints_delta[:delete][name] = from_attrs
568
+ end
569
+ end
570
+
571
+ table_delta[:unique_constraints] = unique_constraints_delta unless unique_constraints_delta.empty?
572
+ end
573
+
508
574
  # XXX: MySQL only?
509
575
  # https://github.com/rails/rails/blob/v4.2.1/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb#L760
510
576
  # https://github.com/rails/rails/blob/v4.2.1/activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb#L102
@@ -106,6 +106,36 @@ module Ridgepole
106
106
  }
107
107
  end
108
108
 
109
+ def add_exclusion_constraint(table_name, expression, options = {})
110
+ table_name = table_name.to_s
111
+ expression = expression.to_s
112
+ options[:name] = options[:name].to_s if options[:name]
113
+
114
+ idx = options[:name] || expression
115
+
116
+ @__definition[table_name] ||= {}
117
+ @__definition[table_name][:exclusion_constraints] ||= {}
118
+ @__definition[table_name][:exclusion_constraints][idx] = {
119
+ expression: expression,
120
+ options: options,
121
+ }
122
+ end
123
+
124
+ def add_unique_constraint(table_name, column_name, options = {})
125
+ table_name = table_name.to_s
126
+ column_name = Array(column_name).map(&:to_sym)
127
+ options[:name] = options[:name].to_s if options[:name]
128
+
129
+ idx = options[:name] || column_name
130
+
131
+ @__definition[table_name] ||= {}
132
+ @__definition[table_name][:unique_constraints] ||= {}
133
+ @__definition[table_name][:unique_constraints][idx] = {
134
+ column_name: column_name,
135
+ options: options,
136
+ }
137
+ end
138
+
109
139
  def require(file)
110
140
  schemafile = %r{\A/}.match?(file) ? file : File.join(@__working_dir, file)
111
141
 
@@ -179,6 +179,14 @@ module Ridgepole
179
179
  def check_constraint(expression, options = {})
180
180
  @base.add_check_constraint(@table_name, expression, options)
181
181
  end
182
+
183
+ def exclusion_constraint(expression, options = {})
184
+ @base.add_exclusion_constraint(@table_name, expression, options)
185
+ end
186
+
187
+ def unique_constraint(column_name, options = {})
188
+ @base.add_unique_constraint(@table_name, column_name, options)
189
+ end
182
190
  end
183
191
  end
184
192
  end
@@ -18,8 +18,6 @@ module Ridgepole
18
18
 
19
19
  if options && @__without_table_options
20
20
  options.delete(:options)
21
-
22
- # For >= AR 6.1.0
23
21
  options.delete(:charset)
24
22
  options.delete(:collation)
25
23
  end
@@ -30,7 +30,7 @@ module Ridgepole
30
30
  remove_prefix_and_suffix(foreign_key.to_table).inspect
31
31
  ]
32
32
 
33
- parts << "column: #{foreign_key.column.inspect}" if foreign_key.column != @connection.foreign_key_column_for(foreign_key.to_table)
33
+ parts << "column: #{foreign_key.column.inspect}" if foreign_key.column != foreign_key_column_for(foreign_key)
34
34
 
35
35
  parts << "primary_key: #{foreign_key.primary_key.inspect}" if foreign_key.custom_primary_key?
36
36
 
@@ -45,6 +45,16 @@ module Ridgepole
45
45
  stream.puts add_foreign_key_statements.sort.join("\n")
46
46
  end
47
47
  end
48
+
49
+ private
50
+
51
+ def foreign_key_column_for(foreign_key)
52
+ if ActiveRecord.gem_version < Gem::Version.new('7.1.0')
53
+ @connection.foreign_key_column_for(foreign_key.to_table)
54
+ else
55
+ @connection.foreign_key_column_for(foreign_key.to_table, 'id')
56
+ end
57
+ end
48
58
  end
49
59
  end
50
60
  end
@@ -8,7 +8,7 @@ module Ridgepole
8
8
  end
9
9
 
10
10
  def execute(sql)
11
- cmd = Shellwords.join([@script, sql, JSON.dump(connection_configuration_hash)])
11
+ cmd = Shellwords.join([@script, sql, JSON.dump(ActiveRecord::Base.connection_db_config.configuration_hash)])
12
12
  @logger.info("Execute #{@script}")
13
13
  script_basename = File.basename(@script)
14
14
 
@@ -46,16 +46,5 @@ module Ridgepole
46
46
  raise "`#{@script}` execution failed" unless wait_thr.value.success?
47
47
  end
48
48
  end
49
-
50
- private
51
-
52
- def connection_configuration_hash
53
- if ActiveRecord.gem_version < Gem::Version.new('6.1.0')
54
- # NOTE: Remove code when stopping support for versions below 6.1
55
- ActiveRecord::Base.connection_config
56
- else
57
- ActiveRecord::Base.connection_db_config.configuration_hash
58
- end
59
- end
60
49
  end
61
50
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ridgepole
4
- VERSION = '1.2.1'
4
+ VERSION = '2.0.0.beta'
5
5
  end
data/ridgepole.gemspec CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.required_ruby_version = Gem::Requirement.new('>= 2.7')
26
26
 
27
- spec.add_dependency 'activerecord', '>= 5.1', '< 7.1'
27
+ spec.add_dependency 'activerecord', '>= 6.1', '< 7.2'
28
28
  spec.add_dependency 'diffy'
29
29
 
30
30
  spec.add_development_dependency 'appraisal', '>= 2.2.0'
@@ -38,7 +38,7 @@ Gem::Specification.new do |spec|
38
38
  spec.add_development_dependency 'rspec', '>= 3.0.0'
39
39
  spec.add_development_dependency 'rspec-match_fuzzy', '>= 0.1.3'
40
40
  spec.add_development_dependency 'rspec-match_ruby', '>= 0.1.3'
41
- spec.add_development_dependency 'rubocop', '1.54.2'
41
+ spec.add_development_dependency 'rubocop', '1.57.1'
42
42
  spec.add_development_dependency 'rubocop-rake', '>= 0.5.1'
43
43
  spec.add_development_dependency 'rubocop-rspec', '>= 2.1.0'
44
44
  spec.add_development_dependency 'simplecov'
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: 1.2.1
4
+ version: 2.0.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Genki Sugawara
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-29 00:00:00.000000000 Z
11
+ date: 2023-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,20 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '5.1'
19
+ version: '6.1'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '7.1'
22
+ version: '7.2'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '5.1'
29
+ version: '6.1'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '7.1'
32
+ version: '7.2'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: diffy
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -204,14 +204,14 @@ dependencies:
204
204
  requirements:
205
205
  - - '='
206
206
  - !ruby/object:Gem::Version
207
- version: 1.54.2
207
+ version: 1.57.1
208
208
  type: :development
209
209
  prerelease: false
210
210
  version_requirements: !ruby/object:Gem::Requirement
211
211
  requirements:
212
212
  - - '='
213
213
  - !ruby/object:Gem::Version
214
- version: 1.54.2
214
+ version: 1.57.1
215
215
  - !ruby/object:Gem::Dependency
216
216
  name: rubocop-rake
217
217
  requirement: !ruby/object:Gem::Requirement
@@ -288,9 +288,9 @@ files:
288
288
  - Rakefile
289
289
  - bin/ridgepole
290
290
  - compose.yml
291
- - gemfiles/activerecord_6.0.gemfile
292
291
  - gemfiles/activerecord_6.1.gemfile
293
292
  - gemfiles/activerecord_7.0.gemfile
293
+ - gemfiles/activerecord_7.1.gemfile
294
294
  - lib/ridgepole.rb
295
295
  - lib/ridgepole/cli/config.rb
296
296
  - lib/ridgepole/client.rb
@@ -330,9 +330,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
330
330
  version: '2.7'
331
331
  required_rubygems_version: !ruby/object:Gem::Requirement
332
332
  requirements:
333
- - - ">="
333
+ - - ">"
334
334
  - !ruby/object:Gem::Version
335
- version: '0'
335
+ version: 1.3.1
336
336
  requirements: []
337
337
  rubygems_version: 3.3.7
338
338
  signing_key: