online_migrations 0.13.1 → 0.14.1

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: 8952366397c54505f364a353dde1d68e988ac4773e9b3663de790a75c8b860f3
4
- data.tar.gz: 376dc6e760a2b07d55968a11097f9f81067bc72291718938d1102fafb46a73ea
3
+ metadata.gz: 330d5ed7f11aae3b85e7fb5aab5a1ea66d809da704cf193420b6d4206f72d82b
4
+ data.tar.gz: 36d47a6f2a1cae3de33331a4ec9e6b21fc7b3b8b09a7d5e9c34d1be6c92e5d35
5
5
  SHA512:
6
- metadata.gz: 3e40ed5ab49e5d702c7d7cfebdb4264621375ad9affb67e8c3592814c4a832e75929c4ff718ce90709e64497226df3d9503a42babf56cfaad5ce973026f71d82
7
- data.tar.gz: cdcbc9c26ac23fb975f21dd58c9826dab59c9571d074da06211dea2ffae72c3c57372722110ecd729ba649f21db551f58e8ca43689214f1235cd20669f033cf6
6
+ metadata.gz: e07937136867b4b6bc2d0dfb2e5ccb8471faf6ce0339a247bc0c63d591cc163e084da731e86fc01ba839c7744a51e9c63e99ce632452e471f9eed98a95b9dd02
7
+ data.tar.gz: f1a33636d5fbd01f25a0cee32af0d74e377c804eaef0feee2c778c5318a93bbe8942dc03e8ea2bad0a610d0046a8d4e42b505d0991c7d215cc9842a24d5e5065
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  ## master (unreleased)
2
2
 
3
+ ## 0.14.1 (2024-02-21)
4
+
5
+ - Fix `MigrationRunner` to consider `run_background_migrations_inline` proc
6
+
7
+ ## 0.14.0 (2024-02-01)
8
+
9
+ - Add ability to configure whether background migrations should be run inline
10
+
11
+ The previous behavior of running inline in development and test environments is preserved, unless overriden.
12
+
13
+ ```ruby
14
+ config.run_background_migrations_inline = -> { Rails.env.local? }
15
+ ```
16
+
3
17
  ## 0.13.1 (2024-01-23)
4
18
 
5
19
  - Fix calculation of batch ranges for background migration created with explicit ranges
data/README.md CHANGED
@@ -206,7 +206,7 @@ end
206
206
  end
207
207
  ```
208
208
 
209
- 4. Remove column ignoring from `User` model
209
+ 4. Remove column ignoring from step 1
210
210
  5. Deploy
211
211
 
212
212
  ### Adding a column with a default value
data/docs/configuring.md CHANGED
@@ -214,6 +214,17 @@ Add to an initializer file:
214
214
  config.auto_analyze = true
215
215
  ```
216
216
 
217
+ ### Running background migrations inline
218
+
219
+ `config.run_background_migrations_inline` can be configured with a proc to decide whether background migrations should be run inline. For convenience defaults to true for development and test environments.
220
+
221
+ ```ruby
222
+ # config/initializers/online_migrations.rb
223
+ config.run_background_migrations_inline = -> { Rails.env.local? }
224
+ ```
225
+
226
+ Set to `nil` to avoid running background migrations inline.
227
+
217
228
  ## Schema Sanity
218
229
 
219
230
  Columns can flip order in `db/schema.rb` when you have multiple developers. One way to prevent this is to [alphabetize them](https://www.pgrs.net/2008/03/12/alphabetize-schema-rb-columns/).
@@ -77,6 +77,10 @@ OnlineMigrations.configure do |config|
77
77
  # end
78
78
  # end
79
79
 
80
+ # Decide whether background migrations should be run inline.
81
+ # Convenient for development and test environments.
82
+ config.run_background_migrations_inline = -> { Rails.env.local? }
83
+
80
84
  # ==> Background migrations configuration
81
85
 
82
86
  # The path where generated background migrations will be placed.
@@ -30,7 +30,12 @@ module OnlineMigrations
30
30
 
31
31
  alias_attribute :name, :migration_name
32
32
 
33
- enum status: STATUSES.index_with(&:to_s)
33
+ # Avoid deprecation warnings.
34
+ if Utils.ar_version >= 7
35
+ enum :status, STATUSES.index_with(&:to_s)
36
+ else
37
+ enum status: STATUSES.index_with(&:to_s)
38
+ end
34
39
 
35
40
  belongs_to :parent, class_name: name, optional: true
36
41
  has_many :children, class_name: name, foreign_key: :parent_id, dependent: :delete_all
@@ -307,7 +307,7 @@ module OnlineMigrations
307
307
  # perform_action_on_relation_in_background("User", { invite_token: nil }, :generate_invite_token)
308
308
  #
309
309
  # @note This method is better suited for large tables (10/100s of millions of records).
310
- # For smaller tables it is probably better and easier to directly delete associated records.
310
+ # For smaller tables it is probably better and easier to directly perform the action on associated records.
311
311
  #
312
312
  def perform_action_on_relation_in_background(model_name, conditions, action, updates: nil, **options)
313
313
  model_name = model_name.name if model_name.is_a?(Class)
@@ -372,8 +372,8 @@ module OnlineMigrations
372
372
  def enqueue_background_migration(migration_name, *arguments, **options)
373
373
  migration = create_background_migration(migration_name, *arguments, **options)
374
374
 
375
- # For convenience in dev/test environments
376
- if Utils.developer_env?
375
+ run_inline = OnlineMigrations.config.run_background_migrations_inline
376
+ if run_inline && run_inline.call
377
377
  runner = MigrationRunner.new(migration)
378
378
  runner.run_all_migration_jobs
379
379
  end
@@ -37,7 +37,12 @@ module OnlineMigrations
37
37
  scope :except_succeeded, -> { where.not(status: :succeeded) }
38
38
  scope :attempts_exceeded, -> { where("attempts >= max_attempts") }
39
39
 
40
- enum status: STATUSES.index_with(&:to_s)
40
+ # Avoid deprecation warnings.
41
+ if Utils.ar_version >= 7
42
+ enum :status, STATUSES.index_with(&:to_s)
43
+ else
44
+ enum status: STATUSES.index_with(&:to_s)
45
+ end
41
46
 
42
47
  delegate :migration_class, :migration_object, :migration_relation, :batch_column_name,
43
48
  :arguments, :batch_pause, to: :migration
@@ -51,7 +51,11 @@ module OnlineMigrations
51
51
  # @note This method should not be used in production environments
52
52
  #
53
53
  def run_all_migration_jobs
54
- raise "This method is not intended for use in production environments" if !Utils.developer_env?
54
+ run_inline = OnlineMigrations.config.run_background_migrations_inline
55
+ if run_inline && !run_inline.call
56
+ raise "This method is not intended for use in production environments"
57
+ end
58
+
55
59
  return if migration.completed?
56
60
 
57
61
  mark_as_running
@@ -100,7 +100,7 @@ module OnlineMigrations
100
100
  end
101
101
 
102
102
  def set_statement_timeout
103
- if !@statement_timeout_set
103
+ if !defined?(@statement_timeout_set)
104
104
  if (statement_timeout = OnlineMigrations.config.statement_timeout)
105
105
  # TODO: inline this method call after deprecated `disable_statement_timeout` method removal.
106
106
  connection.__set_statement_timeout(statement_timeout)
@@ -171,6 +171,16 @@ module OnlineMigrations
171
171
  #
172
172
  attr_accessor :verbose_sql_logs
173
173
 
174
+ # The proc which decides whether background migrations should be run inline.
175
+ # For convenience defaults to true for development and test environments.
176
+ #
177
+ # @example
178
+ # OnlineMigrations.config.run_background_migrations_inline = -> { Rails.env.local? }
179
+ #
180
+ # @return [Proc]
181
+ #
182
+ attr_accessor :run_background_migrations_inline
183
+
174
184
  # Configuration object to configure background migrations
175
185
  #
176
186
  # @return [BackgroundMigrationsConfig]
@@ -202,6 +212,7 @@ module OnlineMigrations
202
212
  @alphabetize_schema = false
203
213
  @enabled_checks = @error_messages.keys.index_with({})
204
214
  @verbose_sql_logs = defined?(Rails.env) && (Rails.env.production? || Rails.env.staging?)
215
+ @run_background_migrations_inline = -> { Utils.developer_env? }
205
216
  end
206
217
 
207
218
  def lock_retrier=(value)
@@ -5,7 +5,7 @@ module OnlineMigrations
5
5
  module DatabaseTasks
6
6
  def migrate(*)
7
7
  super
8
- rescue => e # rubocop:disable Style/RescueStandardError
8
+ rescue => e
9
9
  if e.cause.is_a?(OnlineMigrations::Error)
10
10
  # strip cause
11
11
  def e.cause
@@ -295,7 +295,7 @@ end
295
295
  Active Record caches database columns at runtime, so if you drop a column, it can cause exceptions until your app reboots.
296
296
  A safer approach is to:
297
297
 
298
- 1. Ignore the column(s):
298
+ 1. Ignore the column:
299
299
 
300
300
  class <%= model %> < ApplicationRecord
301
301
  self.ignored_columns = <%= columns %>
@@ -310,7 +310,7 @@ A safer approach is to:
310
310
  end
311
311
  end
312
312
 
313
- 4. Remove columns ignoring
313
+ 4. Remove column ignoring from step 1
314
314
  5. Deploy
315
315
  <% end %>",
316
316
 
@@ -78,7 +78,7 @@ module OnlineMigrations
78
78
  end
79
79
 
80
80
  # @private
81
- module SchemaCache7
81
+ module SchemaCache71
82
82
  # Active Record >= 7.1 changed signature of the methods,
83
83
  # see https://github.com/rails/rails/pull/48716.
84
84
  def primary_keys(connection, table_name)
@@ -154,4 +154,82 @@ module OnlineMigrations
154
154
  columns << new_column.freeze
155
155
  end
156
156
  end
157
+
158
+ # @private
159
+ module SchemaCache72
160
+ # Active Record >= 7.2 changed signature of the methods,
161
+ # see https://github.com/rails/rails/pull/48716.
162
+ def primary_keys(pool, table_name)
163
+ if (renamed_table = renamed_table?(pool, table_name))
164
+ super(pool, renamed_table)
165
+ elsif renamed_column?(pool, table_name)
166
+ super(pool, column_rename_table(table_name))
167
+ else
168
+ super
169
+ end
170
+ end
171
+
172
+ def columns(pool, table_name)
173
+ if (renamed_table = renamed_table?(pool, table_name))
174
+ super(pool, renamed_table)
175
+ elsif renamed_column?(pool, table_name)
176
+ columns = super(pool, column_rename_table(table_name))
177
+ OnlineMigrations.config.column_renames[table_name].each do |old_column_name, new_column_name|
178
+ duplicate_column(old_column_name, new_column_name, columns)
179
+ end
180
+ columns
181
+ else
182
+ super.reject { |column| column.name.end_with?("_for_type_change") }
183
+ end
184
+ end
185
+
186
+ def indexes(pool, table_name)
187
+ if (renamed_table = renamed_table?(pool, table_name))
188
+ super(pool, renamed_table)
189
+ elsif renamed_column?(pool, table_name)
190
+ super(pool, column_rename_table(table_name))
191
+ else
192
+ super
193
+ end
194
+ end
195
+
196
+ def clear_data_source_cache!(pool, name)
197
+ if (renamed_table = renamed_table?(pool, name))
198
+ super(pool, renamed_table)
199
+ end
200
+
201
+ if renamed_column?(pool, name)
202
+ super(pool, column_rename_table(name))
203
+ end
204
+
205
+ super
206
+ end
207
+
208
+ private
209
+ def renamed_table?(pool, table_name)
210
+ table_renames = OnlineMigrations.config.table_renames
211
+ if table_renames.key?(table_name)
212
+ views = pool.with_connection(&:views)
213
+ table_renames[table_name] if views.include?(table_name)
214
+ end
215
+ end
216
+
217
+ def renamed_column?(pool, table_name)
218
+ column_renames = OnlineMigrations.config.column_renames
219
+ column_renames.key?(table_name) && pool.with_connection(&:views).include?(table_name)
220
+ end
221
+
222
+ def column_rename_table(table_name)
223
+ "#{table_name}_column_rename"
224
+ end
225
+
226
+ def duplicate_column(old_column_name, new_column_name, columns)
227
+ old_column = columns.find { |column| column.name == old_column_name }
228
+ new_column = old_column.dup
229
+ # Active Record defines only reader for :name
230
+ new_column.instance_variable_set(:@name, new_column_name)
231
+ # Correspond to the Active Record freezing of each column
232
+ columns << new_column.freeze
233
+ end
234
+ end
157
235
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OnlineMigrations
4
- VERSION = "0.13.1"
4
+ VERSION = "0.14.1"
5
5
  end
@@ -7,6 +7,7 @@ require "online_migrations/utils"
7
7
  require "online_migrations/change_column_type_helpers"
8
8
  require "online_migrations/background_migrations/migration_helpers"
9
9
  require "online_migrations/schema_statements"
10
+ require "online_migrations/schema_cache"
10
11
  require "online_migrations/migration"
11
12
  require "online_migrations/migrator"
12
13
  require "online_migrations/schema_dumper"
@@ -29,11 +30,6 @@ module OnlineMigrations
29
30
  autoload :CommandChecker
30
31
  autoload :BackgroundMigration
31
32
 
32
- autoload_at "online_migrations/schema_cache" do
33
- autoload :SchemaCache
34
- autoload :SchemaCache7
35
- end
36
-
37
33
  autoload_at "online_migrations/lock_retrier" do
38
34
  autoload :LockRetrier
39
35
  autoload :ConstantLockRetrier
@@ -102,8 +98,10 @@ module OnlineMigrations
102
98
  ActiveRecord::Tasks::DatabaseTasks.singleton_class.prepend(OnlineMigrations::DatabaseTasks)
103
99
  ActiveRecord::Migration::CommandRecorder.include(OnlineMigrations::CommandRecorder)
104
100
 
105
- if OnlineMigrations::Utils.ar_version >= 7.1
106
- ActiveRecord::ConnectionAdapters::SchemaCache.prepend(OnlineMigrations::SchemaCache7)
101
+ if OnlineMigrations::Utils.ar_version >= 7.2
102
+ ActiveRecord::ConnectionAdapters::SchemaCache.prepend(OnlineMigrations::SchemaCache72)
103
+ elsif OnlineMigrations::Utils.ar_version >= 7.1
104
+ ActiveRecord::ConnectionAdapters::SchemaCache.prepend(OnlineMigrations::SchemaCache71)
107
105
  else
108
106
  ActiveRecord::ConnectionAdapters::SchemaCache.prepend(OnlineMigrations::SchemaCache)
109
107
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: online_migrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.1
4
+ version: 0.14.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - fatkodima
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-23 00:00:00.000000000 Z
11
+ date: 2024-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord