ridgepole 1.2.1 → 2.0.0.beta

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