vitess-activerecord-migration 0.1.0 → 0.3.0

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: 3eae6c9228eb8d3d5ebae767cef06ff65c89b073e6598bf690ddbd0907e995a0
4
- data.tar.gz: bed613b3ec15ac973a5dabd1957e054d68b5d7adaefb0938af03fba3b7b2be6e
3
+ metadata.gz: ccf02af6a599148167a09bb0281fcb891663bf455b280c74bcd0f344d15b0008
4
+ data.tar.gz: 6fbd1977dd22de177572f0de28dbbd80824b445361c62f0d2f1f7741c8b884ba
5
5
  SHA512:
6
- metadata.gz: bf5fef0a1132c9cc35a7af3314b64da6669653813d90dc50ddb65018ecfa456dc2c25d1b234a8c9a66a7d8f0838b186a0fa281f05249ef58b15e25b084410085
7
- data.tar.gz: 213b03855f9303882dd237db331a7b030f1dfe704d18b70895b71b7dffb120165ce012bb932016dc8ce2ce45e9f18d9722ad77b1b65d6c5acd44ae4e0cf1aec5
6
+ metadata.gz: a02873ccab767abf06dc40277d4f75dd169449d43d1e3b40b08c15ddc099efd89edab6016af640379842c92e1d999e1e112c21a97107eda80b5c0858077f9116
7
+ data.tar.gz: 42336d57e7c0e870a2dae788ab66ed56858683738df9b76094ce87c8df8b09d8844fc878a9679028a9b1de3cc68dde3b37e890b96a5455ef04d56f06f36c9c02
data/.env CHANGED
@@ -1,3 +1,3 @@
1
1
  RUBY_VERSION=${RUBY_VERSION:-3.2}
2
2
  RAILS_VERSION=${RAILS_VERSION:-~> 7.2.0}
3
- VITESS_VERSION=${VITESS_VERSION:-20.0}
3
+ VITESS_VERSION=${VITESS_VERSION:-21.0}
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.3.0] - 2025-08-30
4
+
5
+ - **BREAKING**: Drop Rails 6.1 support, require ActiveRecord >= 7.0 (#7)
6
+ - **BREAKING**: Raise errors on failed/cancelled/timed-out migrations (#5)
7
+
3
8
  ## [0.1.0] - 2024-09-02
4
9
 
5
10
  - Initial release
data/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Vitess::Activerecord::Migration
2
2
 
3
+ [![Ruby](https://github.com/yoheimuta/vitess-activerecord-migration/actions/workflows/main.yml/badge.svg)](https://github.com/yoheimuta/vitess-activerecord-migration/actions/workflows/main.yml)
4
+ [![Gem Version](https://badge.fury.io/rb/vitess-activerecord-migration.svg)](https://badge.fury.io/rb/vitess-activerecord-migration)
5
+ [![License](http://img.shields.io/:license-mit-blue.svg)](https://github.com/yoheimuta/protolint/blob/master/LICENSE)
6
+
3
7
  vitess-activerecord-migration is a gem for integrating Vitess with ActiveRecord migrations.
4
8
 
5
9
  Vitess::Activerecord::Migration provides tools to integrate Vitess with ActiveRecord migrations,
@@ -22,7 +26,7 @@ ActiveRecord::Migration.prepend(Vitess::Activerecord::Migration)
22
26
 
23
27
  The default ddl strategy is `vitess` with no options.
24
28
 
25
- When you want to set the ddl strategy and its options for one shot, you can set them in the migration file.
29
+ When you want to change the ddl strategy and its options for one shot, you can set them in the migration file.
26
30
 
27
31
  ```ruby
28
32
  def default_ddl_strategy
@@ -35,7 +39,7 @@ def change
35
39
  end
36
40
  ```
37
41
 
38
- When you want to set the default ddl strategy and its options, you can override the following methods.
42
+ When you want to change the default ddl strategy and its options, you can override the following methods.
39
43
 
40
44
  ```ruby
41
45
  # lib/vitess/activerecord/app_migration.rb
@@ -57,6 +61,24 @@ ActiveRecord::Migration.prepend(Vitess::Activerecord::Migration)
57
61
  ActiveRecord::Migration.prepend(Vitess::Activerecord::AppMigration)
58
62
  ```
59
63
 
64
+ When you want to change the log parameters during the migration, you can override the following method.
65
+
66
+ ```ruby
67
+ # lib/vitess/activerecord/app_migration.rb
68
+ module Vitess
69
+ module Activerecord
70
+ module AppMigration
71
+ def migration_log_columns
72
+ %w[
73
+ migration_uuid
74
+ progress
75
+ eta_seconds
76
+ ]
77
+ end
78
+ end
79
+ end
80
+ end
81
+ ```
60
82
 
61
83
  ## Development
62
84
 
@@ -3,7 +3,7 @@
3
3
  module Vitess
4
4
  module Activerecord
5
5
  module Migration
6
- VERSION = "0.1.0"
6
+ VERSION = "0.3.0"
7
7
  end
8
8
  end
9
9
  end
@@ -7,6 +7,9 @@ module Vitess
7
7
  module Activerecord
8
8
  module Migration
9
9
  class Error < StandardError; end
10
+ class Failed < Error; end
11
+ class Cancelled < Error; end
12
+ class TimedOut < Error; end
10
13
 
11
14
  # Returns the default DDL strategy.
12
15
  # This method is called and set before executing the change, up, or down methods.
@@ -17,13 +20,41 @@ module Vitess
17
20
  end
18
21
 
19
22
  # Returns the timeout seconds for waiting for the completion of the DDL statement.
20
- # Even after the timeout, the migration on Vitess will not be stopped, but a warning will be logged.
23
+ # If the DDL exceeds the timeout:
24
+ #
25
+ # * A warning will be logged.
26
+ # * An error will be raised and halt the Rails migration if `raise_on_timeout` is `true`.
27
+ # * The Vitess migration will continue.
21
28
  #
22
29
  # Override this method if you want to change the default timeout.
23
30
  def wait_timeout_seconds
24
31
  7200 # 120 minutes
25
32
  end
26
33
 
34
+ # Returns whether an error will be raised when the DDL statement exceeds wait_timeout_seconds.
35
+ #
36
+ # Override this method if you want to change how timeouts are handled.
37
+ def raise_on_timeout
38
+ true
39
+ end
40
+
41
+ # Returns the columns of SHOW VITESS_MIGRATIONS to log during the run.
42
+ #
43
+ # Override this method if you want to change the default columns.
44
+ def migration_log_columns
45
+ %w[
46
+ migration_uuid
47
+ migration_statement
48
+ added_timestamp
49
+ started_timestamp
50
+ last_throttled_timestamp
51
+ last_cutover_attempt_timestamp
52
+ is_immediate_operation
53
+ progress
54
+ eta_seconds
55
+ ]
56
+ end
57
+
27
58
  # Override exec_migration to set the default DDL strategy to vitess.
28
59
  # This method is called every time a migration is executed.
29
60
  # If you want to use a different DDL strategy, call with_ddl_strategy inside the change method or elsewhere.
@@ -97,14 +128,24 @@ module Vitess
97
128
  @stopped_uuid ||= []
98
129
 
99
130
  loop do
131
+ # A Rails migration will create a separate Vitess migration for each DDL submitted by Rails.
132
+ # Each Rails migration has a unique version and this is used to group the resulting Vitess migrations using the `migration_context` field.
133
+ # Vitess records the DDL submitted by Rails in the `migration_statement` column.
134
+ # If the Rails migration fails and is later retried, Vitess will create additional Vitess migrations with the same `migration_context` from the previous attempt.
135
+ # Vitess will immediately mark "duplicate" DDLs that were previously successful as complete.
136
+ # Vitess will retry "duplicate" DDLs that were previously unsuccessful.
137
+ # The overall Rails migration status is determined by the `migration_status` of the last Vitess migration of each DDL.
138
+ # For details on Vitess duplicate migration detection, see:
139
+ # https://vitess.io/docs/22.0/user-guides/schema-changes/advanced-usage/
100
140
  migrations = ActiveRecord::Base.connection.select_all("SHOW VITESS_MIGRATIONS LIKE '#{@migration_context}'")
141
+ .group_by { |migration| migration['migration_statement'] }
142
+ .map { |_, migrations| migrations.last }
101
143
 
102
144
  migrations.each do |migration|
103
145
  id = migration["id"]
104
146
  next if @stopped_uuid.include?(id)
105
147
 
106
- details = %w[migration_uuid migration_statement added_timestamp started_timestamp is_immediate_operation progress eta_seconds retries]
107
- detail_message = details.map { |column| "#{column}: #{migration[column]}" }.join(" | ")
148
+ detail_message = migration_log_columns.map { |column| "#{column}: #{migration[column]}" }.join(" | ")
108
149
  Rails.logger.info("Vitess Migration #{id} checking status, #{detail_message}")
109
150
 
110
151
  status = migration["migration_status"]
@@ -114,8 +155,10 @@ module Vitess
114
155
  Rails.logger.info("Vitess Migration #{id} completed successfully at #{migration["completed_timestamp"]}")
115
156
  when "failed"
116
157
  Rails.logger.error("Vitess Migration #{id} failed: #{migration["message"]} at #{migration["completed_timestamp"]}")
158
+ raise Failed, "Vitess Migration #{id} failed: #{migration["message"]}"
117
159
  when "cancelled"
118
160
  Rails.logger.warn("Vitess Migration #{id} was cancelled at #{migration["cancelled_timestamp"]}")
161
+ raise Cancelled, "Vitess Migration #{id} was cancelled: #{migration["message"]}"
119
162
  end
120
163
  @stopped_uuid << id
121
164
  else
@@ -130,6 +173,7 @@ module Vitess
130
173
 
131
174
  if Time.now - start_time > timeout_seconds
132
175
  Rails.logger.warn("Vitess Migration did not complete within #{timeout_seconds} seconds. Timing out.")
176
+ raise TimedOut, "Vitess Migration did not complete within #{timeout_seconds} seconds."
133
177
  break
134
178
  end
135
179
 
@@ -138,6 +182,8 @@ module Vitess
138
182
  interval_seconds = [interval_seconds * 2, max_interval_seconds].min
139
183
  end
140
184
  rescue => e
185
+ raise e if [Failed, Cancelled].include?(e.class)
186
+ raise e if e.class == TimedOut && raise_on_timeout
141
187
  Rails.logger.error("An error occurred while waiting for Vitess DDL: #{e.message}")
142
188
  Rails.logger.error(e.backtrace.join("\n"))
143
189
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vitess-activerecord-migration
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yohei Yoshimuta
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-10-07 00:00:00.000000000 Z
11
+ date: 2025-08-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,20 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '6'
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: '8.1'
19
+ version: '7.0'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - ">="
28
25
  - !ruby/object:Gem::Version
29
- version: '6'
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: '8.1'
26
+ version: '7.0'
33
27
  description: Vitess::Activerecord::Migration provides tools to integrate Vitess with
34
28
  ActiveRecord migrations, allowing for seamless database schema changes in a Vitess
35
29
  environment.
@@ -57,7 +51,6 @@ files:
57
51
  - sig/rails_support.rbs
58
52
  - sig/vitess/activerecord/migration.rbs
59
53
  - tmp/.keep
60
- - vitess-activerecord-migration.gemspec
61
54
  homepage: https://github.com/yoheimuta/vitess-activerecord-migration
62
55
  licenses:
63
56
  - MIT
@@ -66,7 +59,7 @@ metadata:
66
59
  homepage_uri: https://github.com/yoheimuta/vitess-activerecord-migration
67
60
  source_code_uri: https://github.com/yoheimuta/vitess-activerecord-migration
68
61
  changelog_uri: https://github.com/yoheimuta/vitess-activerecord-migration/blob/main/CHANGELOG.md
69
- post_install_message:
62
+ post_install_message:
70
63
  rdoc_options: []
71
64
  require_paths:
72
65
  - lib
@@ -81,8 +74,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
74
  - !ruby/object:Gem::Version
82
75
  version: '0'
83
76
  requirements: []
84
- rubygems_version: 3.0.3.1
85
- signing_key:
77
+ rubygems_version: 3.4.10
78
+ signing_key:
86
79
  specification_version: 4
87
80
  summary: A gem for integrating Vitess with ActiveRecord migrations.
88
81
  test_files: []
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "lib/vitess/activerecord/migration/version"
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = "vitess-activerecord-migration"
7
- spec.version = Vitess::Activerecord::Migration::VERSION
8
- spec.authors = ["Yohei Yoshimuta"]
9
- spec.email = ["yoheimuta@gmail.com"]
10
-
11
- spec.summary = "A gem for integrating Vitess with ActiveRecord migrations."
12
- spec.description = "Vitess::Activerecord::Migration provides tools to integrate Vitess with ActiveRecord migrations, allowing for seamless database schema changes in a Vitess environment."
13
- spec.homepage = "https://github.com/yoheimuta/vitess-activerecord-migration"
14
- spec.license = "MIT"
15
- spec.required_ruby_version = ">= 2.7.0"
16
-
17
- spec.metadata["allowed_push_host"] = "https://rubygems.org"
18
-
19
- spec.metadata["homepage_uri"] = spec.homepage
20
- spec.metadata["source_code_uri"] = "https://github.com/yoheimuta/vitess-activerecord-migration"
21
- spec.metadata["changelog_uri"] = "https://github.com/yoheimuta/vitess-activerecord-migration/blob/main/CHANGELOG.md"
22
-
23
- # Specify which files should be added to the gem when it is released.
24
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
- spec.files = Dir.chdir(__dir__) do
26
- `git ls-files -z`.split("\x0").reject do |f|
27
- (File.expand_path(f) == __FILE__) ||
28
- f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile])
29
- end
30
- end
31
- spec.bindir = "exe"
32
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
33
- spec.require_paths = ["lib"]
34
-
35
- # Uncomment to register a new dependency of your gem
36
- spec.add_dependency "activerecord", ">= 6", "< 8.1"
37
-
38
- # For more information and examples about making a new gem, check out our
39
- # guide at: https://bundler.io/guides/creating_gem.html
40
- end