ridgepole 3.0.0 → 3.0.2

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: 2f47329a42a0f1fae570e9c37d7ac12b21b2d542dd1f2a461c43e6f14813dd44
4
- data.tar.gz: 1c0b84ce805e2aecb9fd12b5fdb5be9f9657468ba1f80bc6cee8d0611863458c
3
+ metadata.gz: 443c4cdeceedc5ddc1e9f3fc7cfbede2d2454cf3bc8fedd1b747ad5f0656db2e
4
+ data.tar.gz: 4d392f5b8328132651bf8e6b47505a20457756699f749380eefe9060f0ef86a0
5
5
  SHA512:
6
- metadata.gz: 396a8059a3db35168cda1fba372e923561356230a7f8ffa8e0ee50bfbf51960c3f39b3e6469c34f0b2221d855954ecad20893f5d3d4b9f292893de38b5f758ba
7
- data.tar.gz: f3a4bad14973e545a1a35593b08d26717f15fe5b7b9a32c2178efb84e8b6e99058dd377ae9a7f2ab54737b6cda7d8e678070362c6cce7f4dadc3ca37f7153319
6
+ metadata.gz: d4fbf8b89d03a6477ef56867faeddd2f9bc6f51f359d04426ef8752bdc5ea58f970d27df156e0c2f874a9bd6676a2520fbf413b9a17457c48d05a1870f518f4c
7
+ data.tar.gz: 87696482e889b7e753b6c17c58f8085814f9c0f5bce7e4a2cc151efd64aba12fad8068bf0f107c5f63667d2fd760ea422eb4787df16a9573a4c5f0072ea0b2c5
data/.rubocop.yml CHANGED
@@ -58,3 +58,7 @@ Style/OptionalBooleanParameter:
58
58
  Enabled: false
59
59
  Gemspec/DevelopmentDependencies:
60
60
  Enabled: false
61
+ Lint/LiteralInInterpolation:
62
+ Enabled: false
63
+ Naming/PredicateMethod:
64
+ Enabled: false
data/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  ## 3.0
4
4
 
5
+ ### 3.0.2 (2025/06/22)
6
+
7
+ - Faster table definition comparisons [pull#549](https://github.com/ridgepole/ridgepole/pull/549)
8
+
9
+ ### 3.0.1 (2025/01/12)
10
+
11
+ - Normalize `check_constraint` [pull#512](https://github.com/ridgepole/ridgepole/pull/512)
12
+ - Support composite foreign key for non-primary key [pull#518](https://github.com/ridgepole/ridgepole/pull/518)
13
+
5
14
  ### 3.0.0 (2024/11/10)
6
15
 
7
16
  - Support Rails 8.0 [pull#504](https://github.com/ridgepole/ridgepole/pull/504)
data/README.md CHANGED
@@ -6,8 +6,8 @@ It defines DB schema using [Rails DSL](http://guides.rubyonrails.org/migrations.
6
6
  (like Chef/Puppet)
7
7
 
8
8
  [![Gem Version](https://badge.fury.io/rb/ridgepole.svg)](https://badge.fury.io/rb/ridgepole)
9
- [![Build Status](https://github.com/ridgepole/ridgepole/workflows/test/badge.svg?branch=1.2)](https://github.com/ridgepole/ridgepole/actions)
10
- [![Coverage Status](https://coveralls.io/repos/github/ridgepole/ridgepole/badge.svg?branch=1.2)](https://coveralls.io/github/ridgepole/ridgepole?branch=1.2)
9
+ [![test](https://github.com/ridgepole/ridgepole/actions/workflows/test.yml/badge.svg)](https://github.com/ridgepole/ridgepole/actions/workflows/test.yml)
10
+ [![Coverage Status](https://coveralls.io/repos/github/ridgepole/ridgepole/badge.svg?branch=3.0)](https://coveralls.io/github/ridgepole/ridgepole?branch=3.0)
11
11
 
12
12
  > [!note]
13
13
  > * ridgepole v3.0.0
@@ -271,7 +271,7 @@ create_table(#{table_name.inspect}, #{inspect_options_include_default_proc(optio
271
271
  end
272
272
  RUBY
273
273
 
274
- if !(@options[:create_table_with_index]) && !indices.empty?
274
+ if !@options[:create_table_with_index] && !indices.empty?
275
275
  append_change_table(table_name, buf) do
276
276
  indices.each do |index_name, index_attrs|
277
277
  append_add_index(table_name, index_name, index_attrs, buf)
@@ -3,6 +3,7 @@
3
3
  module Ridgepole
4
4
  class Diff
5
5
  PRIMARY_KEY_OPTIONS = %i[id limit default null precision scale collation unsigned].freeze
6
+ REGEX_COLUMN_IDENTIFIER_QUOTATION_CHARS = '"`'
6
7
 
7
8
  def initialize(options = {})
8
9
  @options = options
@@ -29,8 +30,9 @@ module Ridgepole
29
30
  @logger.verbose_info("# #{table_name}")
30
31
 
31
32
  unless @options[:drop_table_only]
32
- unless (attrs_delta = diff_inspect(from_attrs, to_attrs)).empty?
33
- @logger.verbose_info(attrs_delta)
33
+ unless hash_deep_equal?(from_attrs, to_attrs)
34
+ attrs_delta = diff_inspect(from_attrs, to_attrs)
35
+ @logger.verbose_info(attrs_delta) unless attrs_delta.empty?
34
36
  end
35
37
 
36
38
  scan_change(table_name, from_attrs, to_attrs, delta)
@@ -413,7 +415,7 @@ module Ridgepole
413
415
  end
414
416
  end
415
417
 
416
- if opts[:size] && (attrs[:type] == :text || attrs[:type] == :blob || attrs[:type] == :binary)
418
+ if opts[:size] && %i[text blob binary].include?(attrs[:type])
417
419
  case opts.delete(:size)
418
420
  when :tiny
419
421
  attrs[:type] = :blob if attrs[:type] == :binary
@@ -486,7 +488,7 @@ module Ridgepole
486
488
  from_attrs = from.delete(name)
487
489
 
488
490
  if from_attrs
489
- if from_attrs != to_attrs
491
+ if normalize_check_constraint(from_attrs) != normalize_check_constraint(to_attrs)
490
492
  check_constraints_delta[:add] ||= {}
491
493
  check_constraints_delta[:add][name] = to_attrs
492
494
 
@@ -509,6 +511,12 @@ module Ridgepole
509
511
  table_delta[:check_constraints] = check_constraints_delta unless check_constraints_delta.empty?
510
512
  end
511
513
 
514
+ def normalize_check_constraint(attr)
515
+ attr = attr.dup
516
+ attr[:expression] = attr[:expression].delete(REGEX_COLUMN_IDENTIFIER_QUOTATION_CHARS)
517
+ attr
518
+ end
519
+
512
520
  def scan_exclusion_constraints_change(from, to, table_delta)
513
521
  from = (from || {}).dup
514
522
  to = (to || {}).dup
@@ -725,5 +733,16 @@ module Ridgepole
725
733
  @logger.warn "[WARNING] '#{table_name}' definition is not found" unless definition.key?(table_name)
726
734
  end
727
735
  end
736
+
737
+ def hash_deep_equal?(hash1, hash2)
738
+ return false unless hash1.is_a?(Hash) && hash2.is_a?(Hash)
739
+ return false if hash1.keys.to_set != hash2.keys.to_set
740
+
741
+ hash1.each do |k, v|
742
+ return false unless hash2.key?(k) && v == hash2[k]
743
+ end
744
+
745
+ true
746
+ end
728
747
  end
729
748
  end
@@ -77,8 +77,16 @@ module Ridgepole
77
77
  from_table = from_table.to_s
78
78
  to_table = to_table.to_s
79
79
  options[:name] = options[:name].to_s if options[:name]
80
- options[:primary_key] = options[:primary_key].to_s if options[:primary_key]
81
- options[:column] = options[:column].to_s if options[:column]
80
+ if options[:primary_key].is_a?(Array)
81
+ options[:primary_key] = options[:primary_key].map(&:to_s)
82
+ elsif options[:primary_key]
83
+ options[:primary_key] = options[:primary_key].to_s
84
+ end
85
+ if options[:column].is_a?(Array)
86
+ options[:column] = options[:column].map(&:to_s)
87
+ elsif options[:column]
88
+ options[:column] = options[:column].to_s
89
+ end
82
90
  @__definition[from_table] ||= {}
83
91
  @__definition[from_table][:foreign_keys] ||= {}
84
92
  idx = options[:name] || [from_table, to_table, options[:column]]
@@ -23,11 +23,11 @@ module Ridgepole
23
23
  end
24
24
 
25
25
  def check_orphan_index(table_name, attrs)
26
- raise "Table `#{table_name}` to create the index is not defined: #{attrs[:indices].keys.join(',')}" if attrs[:indices] && !(attrs[:definition])
26
+ raise "Table `#{table_name}` to create the index is not defined: #{attrs[:indices].keys.join(',')}" if attrs[:indices] && !attrs[:definition]
27
27
  end
28
28
 
29
29
  def check_orphan_foreign_key(table_name, attrs)
30
- raise "Table `#{table_name}` to create the foreign key is not defined: #{attrs[:foreign_keys].keys.join(',')}" if attrs[:foreign_keys] && !(attrs[:definition])
30
+ raise "Table `#{table_name}` to create the foreign key is not defined: #{attrs[:foreign_keys].keys.join(',')}" if attrs[:foreign_keys] && !attrs[:definition]
31
31
  end
32
32
 
33
33
  def check_foreign_key_without_index(table_name, attrs)
@@ -36,14 +36,22 @@ module Ridgepole
36
36
 
37
37
  attrs[:foreign_keys].each_value do |foreign_key_attrs|
38
38
  fk_index = foreign_key_attrs[:options][:column] || "#{foreign_key_attrs[:to_table].singularize}_id"
39
- next if attrs[:indices]&.any? { |_k, v| v[:column_name].first == 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
39
+ next if attrs[:indices]&.any? { |_, v| match_column_name?(v[:column_name], fk_index) }
40
+ next if match_column_name?(attrs[:options][:primary_key], fk_index)
42
41
 
43
42
  raise("The column `#{fk_index}` of the table `#{table_name}` has a foreign key but no index. " \
44
43
  'Although InnoDB creates an index automatically, ' \
45
44
  'please add one explicitly in order for ridgepole to manage it.')
46
45
  end
47
46
  end
47
+
48
+ def match_column_name?(index_column_name, fk_index)
49
+ if fk_index.is_a?(Array)
50
+ index_column_name == fk_index
51
+ else
52
+ # NOTE: For composite primary keys, the first column of the primary key is used as the foreign key index
53
+ Array(index_column_name).first == fk_index
54
+ end
55
+ end
48
56
  end
49
57
  end
@@ -85,7 +85,7 @@ module Ridgepole
85
85
  end
86
86
 
87
87
  def target?(table_name)
88
- !(@options[:tables]) || @options[:tables].include?(table_name)
88
+ !@options[:tables] || @options[:tables].include?(table_name)
89
89
  end
90
90
 
91
91
  def dump_from(conn)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ridgepole
4
- VERSION = '3.0.0'
4
+ VERSION = '3.0.2'
5
5
  end
data/lib/ridgepole.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'logger'
4
4
  require 'open3'
5
- require 'pp' # rubocop:disable Lint/RedundantRequireStatement
5
+ require 'pp'
6
6
  require 'shellwords'
7
7
  require 'singleton'
8
8
  require 'stringio'
data/ridgepole.gemspec CHANGED
@@ -13,6 +13,7 @@ Gem::Specification.new do |spec|
13
13
  spec.description = 'Ridgepole is a tool to manage DB schema. It defines DB schema using Rails DSL, and updates DB schema according to DSL.'
14
14
  spec.homepage = 'https://github.com/ridgepole/ridgepole'
15
15
  spec.license = 'MIT'
16
+ spec.platform = Gem::Platform::RUBY
16
17
 
17
18
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
18
19
  `git ls-files -z`.split("\x0").reject do |f|
@@ -40,7 +41,7 @@ Gem::Specification.new do |spec|
40
41
  spec.add_development_dependency 'rspec', '>= 3.0.0'
41
42
  spec.add_development_dependency 'rspec-match_fuzzy', '>= 0.2.0'
42
43
  spec.add_development_dependency 'rspec-match_ruby', '>= 0.1.3'
43
- spec.add_development_dependency 'rubocop', '1.68.0'
44
+ spec.add_development_dependency 'rubocop', '1.76.1'
44
45
  spec.add_development_dependency 'rubocop-rake', '>= 0.5.1'
45
46
  spec.add_development_dependency 'rubocop-rspec', '>= 2.1.0'
46
47
  spec.add_development_dependency 'simplecov'
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ridgepole
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Genki Sugawara
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-11-10 00:00:00.000000000 Z
10
+ date: 2025-06-22 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: activerecord
@@ -232,14 +231,14 @@ dependencies:
232
231
  requirements:
233
232
  - - '='
234
233
  - !ruby/object:Gem::Version
235
- version: 1.68.0
234
+ version: 1.76.1
236
235
  type: :development
237
236
  prerelease: false
238
237
  version_requirements: !ruby/object:Gem::Requirement
239
238
  requirements:
240
239
  - - '='
241
240
  - !ruby/object:Gem::Version
242
- version: 1.68.0
241
+ version: 1.76.1
243
242
  - !ruby/object:Gem::Dependency
244
243
  name: rubocop-rake
245
244
  requirement: !ruby/object:Gem::Requirement
@@ -363,7 +362,6 @@ licenses:
363
362
  - MIT
364
363
  metadata:
365
364
  rubygems_mfa_required: 'true'
366
- post_install_message:
367
365
  rdoc_options: []
368
366
  require_paths:
369
367
  - lib
@@ -378,8 +376,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
378
376
  - !ruby/object:Gem::Version
379
377
  version: '0'
380
378
  requirements: []
381
- rubygems_version: 3.5.20
382
- signing_key:
379
+ rubygems_version: 3.6.1
383
380
  specification_version: 4
384
381
  summary: Ridgepole is a tool to manage DB schema.
385
382
  test_files: []