activerecord 7.0.8.7 → 7.1.0.beta1

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.
Files changed (227) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1339 -1572
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +15 -16
  5. data/lib/active_record/aggregations.rb +16 -13
  6. data/lib/active_record/association_relation.rb +1 -1
  7. data/lib/active_record/associations/association.rb +18 -3
  8. data/lib/active_record/associations/association_scope.rb +16 -9
  9. data/lib/active_record/associations/belongs_to_association.rb +14 -6
  10. data/lib/active_record/associations/builder/association.rb +3 -3
  11. data/lib/active_record/associations/builder/belongs_to.rb +21 -8
  12. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
  13. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  14. data/lib/active_record/associations/collection_association.rb +17 -9
  15. data/lib/active_record/associations/collection_proxy.rb +16 -11
  16. data/lib/active_record/associations/foreign_association.rb +10 -3
  17. data/lib/active_record/associations/has_many_association.rb +20 -13
  18. data/lib/active_record/associations/has_many_through_association.rb +10 -6
  19. data/lib/active_record/associations/has_one_association.rb +10 -3
  20. data/lib/active_record/associations/join_dependency.rb +10 -8
  21. data/lib/active_record/associations/preloader/association.rb +27 -6
  22. data/lib/active_record/associations/preloader.rb +12 -9
  23. data/lib/active_record/associations/singular_association.rb +1 -1
  24. data/lib/active_record/associations/through_association.rb +22 -11
  25. data/lib/active_record/associations.rb +193 -97
  26. data/lib/active_record/attribute_assignment.rb +0 -2
  27. data/lib/active_record/attribute_methods/before_type_cast.rb +17 -0
  28. data/lib/active_record/attribute_methods/dirty.rb +40 -26
  29. data/lib/active_record/attribute_methods/primary_key.rb +76 -24
  30. data/lib/active_record/attribute_methods/query.rb +28 -16
  31. data/lib/active_record/attribute_methods/read.rb +18 -5
  32. data/lib/active_record/attribute_methods/serialization.rb +150 -31
  33. data/lib/active_record/attribute_methods/write.rb +3 -3
  34. data/lib/active_record/attribute_methods.rb +105 -21
  35. data/lib/active_record/attributes.rb +3 -3
  36. data/lib/active_record/autosave_association.rb +55 -9
  37. data/lib/active_record/base.rb +7 -2
  38. data/lib/active_record/callbacks.rb +10 -24
  39. data/lib/active_record/coders/column_serializer.rb +61 -0
  40. data/lib/active_record/coders/json.rb +1 -1
  41. data/lib/active_record/coders/yaml_column.rb +70 -42
  42. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +163 -88
  43. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +2 -0
  44. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +3 -1
  45. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +63 -43
  46. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
  47. data/lib/active_record/connection_adapters/abstract/database_statements.rb +109 -32
  48. data/lib/active_record/connection_adapters/abstract/query_cache.rb +60 -22
  49. data/lib/active_record/connection_adapters/abstract/quoting.rb +41 -6
  50. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  51. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +18 -4
  52. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +137 -11
  53. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +289 -122
  54. data/lib/active_record/connection_adapters/abstract/transaction.rb +280 -58
  55. data/lib/active_record/connection_adapters/abstract_adapter.rb +502 -91
  56. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +200 -108
  57. data/lib/active_record/connection_adapters/column.rb +9 -0
  58. data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
  59. data/lib/active_record/connection_adapters/mysql/database_statements.rb +22 -143
  60. data/lib/active_record/connection_adapters/mysql/quoting.rb +16 -12
  61. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
  62. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +6 -0
  63. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
  64. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +17 -12
  65. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +148 -0
  66. data/lib/active_record/connection_adapters/mysql2_adapter.rb +98 -53
  67. data/lib/active_record/connection_adapters/pool_config.rb +14 -5
  68. data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
  69. data/lib/active_record/connection_adapters/postgresql/column.rb +1 -2
  70. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +76 -29
  71. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +11 -2
  72. data/lib/active_record/connection_adapters/postgresql/quoting.rb +9 -6
  73. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +3 -9
  74. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -6
  75. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +131 -2
  76. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +42 -0
  77. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +351 -54
  78. data/lib/active_record/connection_adapters/postgresql_adapter.rb +336 -168
  79. data/lib/active_record/connection_adapters/schema_cache.rb +287 -59
  80. data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
  81. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +42 -36
  82. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +4 -3
  83. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +1 -0
  84. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +26 -7
  85. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +162 -77
  86. data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
  87. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +98 -0
  88. data/lib/active_record/connection_adapters/trilogy_adapter.rb +254 -0
  89. data/lib/active_record/connection_adapters.rb +3 -1
  90. data/lib/active_record/connection_handling.rb +71 -94
  91. data/lib/active_record/core.rb +128 -138
  92. data/lib/active_record/counter_cache.rb +46 -25
  93. data/lib/active_record/database_configurations/database_config.rb +9 -3
  94. data/lib/active_record/database_configurations/hash_config.rb +22 -12
  95. data/lib/active_record/database_configurations/url_config.rb +17 -11
  96. data/lib/active_record/database_configurations.rb +86 -33
  97. data/lib/active_record/delegated_type.rb +8 -3
  98. data/lib/active_record/deprecator.rb +7 -0
  99. data/lib/active_record/destroy_association_async_job.rb +2 -0
  100. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  101. data/lib/active_record/encryption/cipher/aes256_gcm.rb +4 -1
  102. data/lib/active_record/encryption/config.rb +25 -1
  103. data/lib/active_record/encryption/configurable.rb +12 -19
  104. data/lib/active_record/encryption/context.rb +10 -3
  105. data/lib/active_record/encryption/contexts.rb +5 -1
  106. data/lib/active_record/encryption/derived_secret_key_provider.rb +8 -2
  107. data/lib/active_record/encryption/encryptable_record.rb +36 -18
  108. data/lib/active_record/encryption/encrypted_attribute_type.rb +17 -6
  109. data/lib/active_record/encryption/extended_deterministic_queries.rb +66 -54
  110. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +2 -2
  111. data/lib/active_record/encryption/key_generator.rb +12 -1
  112. data/lib/active_record/encryption/message_serializer.rb +2 -0
  113. data/lib/active_record/encryption/properties.rb +3 -3
  114. data/lib/active_record/encryption/scheme.rb +19 -22
  115. data/lib/active_record/encryption.rb +1 -0
  116. data/lib/active_record/enum.rb +113 -26
  117. data/lib/active_record/errors.rb +89 -15
  118. data/lib/active_record/explain.rb +23 -3
  119. data/lib/active_record/fixture_set/model_metadata.rb +14 -4
  120. data/lib/active_record/fixture_set/render_context.rb +2 -0
  121. data/lib/active_record/fixture_set/table_row.rb +29 -8
  122. data/lib/active_record/fixtures.rb +119 -71
  123. data/lib/active_record/future_result.rb +30 -5
  124. data/lib/active_record/gem_version.rb +4 -4
  125. data/lib/active_record/inheritance.rb +30 -16
  126. data/lib/active_record/insert_all.rb +55 -8
  127. data/lib/active_record/integration.rb +8 -8
  128. data/lib/active_record/internal_metadata.rb +118 -30
  129. data/lib/active_record/locking/pessimistic.rb +5 -2
  130. data/lib/active_record/log_subscriber.rb +29 -12
  131. data/lib/active_record/marshalling.rb +56 -0
  132. data/lib/active_record/message_pack.rb +124 -0
  133. data/lib/active_record/middleware/database_selector/resolver.rb +4 -0
  134. data/lib/active_record/middleware/database_selector.rb +5 -7
  135. data/lib/active_record/middleware/shard_selector.rb +3 -1
  136. data/lib/active_record/migration/command_recorder.rb +100 -4
  137. data/lib/active_record/migration/compatibility.rb +131 -5
  138. data/lib/active_record/migration/default_strategy.rb +23 -0
  139. data/lib/active_record/migration/execution_strategy.rb +19 -0
  140. data/lib/active_record/migration.rb +213 -109
  141. data/lib/active_record/model_schema.rb +47 -27
  142. data/lib/active_record/nested_attributes.rb +28 -3
  143. data/lib/active_record/normalization.rb +158 -0
  144. data/lib/active_record/persistence.rb +183 -33
  145. data/lib/active_record/promise.rb +84 -0
  146. data/lib/active_record/query_cache.rb +3 -21
  147. data/lib/active_record/query_logs.rb +77 -52
  148. data/lib/active_record/query_logs_formatter.rb +41 -0
  149. data/lib/active_record/querying.rb +15 -2
  150. data/lib/active_record/railtie.rb +107 -45
  151. data/lib/active_record/railties/controller_runtime.rb +10 -5
  152. data/lib/active_record/railties/databases.rake +139 -145
  153. data/lib/active_record/railties/job_runtime.rb +23 -0
  154. data/lib/active_record/readonly_attributes.rb +32 -5
  155. data/lib/active_record/reflection.rb +169 -45
  156. data/lib/active_record/relation/batches/batch_enumerator.rb +5 -3
  157. data/lib/active_record/relation/batches.rb +190 -61
  158. data/lib/active_record/relation/calculations.rb +152 -63
  159. data/lib/active_record/relation/delegation.rb +22 -8
  160. data/lib/active_record/relation/finder_methods.rb +85 -15
  161. data/lib/active_record/relation/merger.rb +2 -0
  162. data/lib/active_record/relation/predicate_builder/association_query_value.rb +11 -2
  163. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  164. data/lib/active_record/relation/predicate_builder.rb +26 -14
  165. data/lib/active_record/relation/query_attribute.rb +2 -1
  166. data/lib/active_record/relation/query_methods.rb +351 -62
  167. data/lib/active_record/relation/spawn_methods.rb +18 -1
  168. data/lib/active_record/relation.rb +76 -35
  169. data/lib/active_record/result.rb +19 -5
  170. data/lib/active_record/runtime_registry.rb +10 -1
  171. data/lib/active_record/sanitization.rb +51 -11
  172. data/lib/active_record/schema.rb +2 -3
  173. data/lib/active_record/schema_dumper.rb +41 -7
  174. data/lib/active_record/schema_migration.rb +68 -33
  175. data/lib/active_record/scoping/default.rb +15 -5
  176. data/lib/active_record/scoping/named.rb +2 -2
  177. data/lib/active_record/scoping.rb +2 -1
  178. data/lib/active_record/secure_password.rb +60 -0
  179. data/lib/active_record/secure_token.rb +21 -3
  180. data/lib/active_record/signed_id.rb +7 -5
  181. data/lib/active_record/store.rb +8 -8
  182. data/lib/active_record/suppressor.rb +3 -1
  183. data/lib/active_record/table_metadata.rb +10 -1
  184. data/lib/active_record/tasks/database_tasks.rb +127 -105
  185. data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
  186. data/lib/active_record/tasks/postgresql_database_tasks.rb +16 -13
  187. data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -7
  188. data/lib/active_record/test_fixtures.rb +113 -96
  189. data/lib/active_record/timestamp.rb +26 -14
  190. data/lib/active_record/token_for.rb +113 -0
  191. data/lib/active_record/touch_later.rb +11 -6
  192. data/lib/active_record/transactions.rb +36 -10
  193. data/lib/active_record/type/adapter_specific_registry.rb +1 -8
  194. data/lib/active_record/type/internal/timezone.rb +7 -2
  195. data/lib/active_record/type/time.rb +4 -0
  196. data/lib/active_record/validations/absence.rb +1 -1
  197. data/lib/active_record/validations/numericality.rb +5 -4
  198. data/lib/active_record/validations/presence.rb +5 -28
  199. data/lib/active_record/validations/uniqueness.rb +47 -2
  200. data/lib/active_record/validations.rb +8 -4
  201. data/lib/active_record/version.rb +1 -1
  202. data/lib/active_record.rb +121 -16
  203. data/lib/arel/errors.rb +10 -0
  204. data/lib/arel/factory_methods.rb +4 -0
  205. data/lib/arel/nodes/binary.rb +6 -1
  206. data/lib/arel/nodes/bound_sql_literal.rb +61 -0
  207. data/lib/arel/nodes/cte.rb +36 -0
  208. data/lib/arel/nodes/fragments.rb +35 -0
  209. data/lib/arel/nodes/homogeneous_in.rb +0 -8
  210. data/lib/arel/nodes/leading_join.rb +8 -0
  211. data/lib/arel/nodes/node.rb +111 -2
  212. data/lib/arel/nodes/sql_literal.rb +6 -0
  213. data/lib/arel/nodes/table_alias.rb +4 -0
  214. data/lib/arel/nodes.rb +4 -0
  215. data/lib/arel/predications.rb +2 -0
  216. data/lib/arel/table.rb +9 -5
  217. data/lib/arel/visitors/mysql.rb +8 -1
  218. data/lib/arel/visitors/to_sql.rb +81 -17
  219. data/lib/arel/visitors/visitor.rb +2 -2
  220. data/lib/arel.rb +16 -2
  221. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  222. data/lib/rails/generators/active_record/migration.rb +3 -1
  223. data/lib/rails/generators/active_record/model/USAGE +113 -0
  224. data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
  225. metadata +52 -17
  226. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
  227. data/lib/active_record/null_relation.rb +0 -63
@@ -20,7 +20,7 @@ module ActiveRecord
20
20
  # For example the following migration is not reversible.
21
21
  # Rolling back this migration will raise an ActiveRecord::IrreversibleMigration error.
22
22
  #
23
- # class IrreversibleMigrationExample < ActiveRecord::Migration[7.0]
23
+ # class IrreversibleMigrationExample < ActiveRecord::Migration[7.1]
24
24
  # def change
25
25
  # create_table :distributors do |t|
26
26
  # t.string :zipcode
@@ -38,7 +38,7 @@ module ActiveRecord
38
38
  #
39
39
  # 1. Define <tt>#up</tt> and <tt>#down</tt> methods instead of <tt>#change</tt>:
40
40
  #
41
- # class ReversibleMigrationExample < ActiveRecord::Migration[7.0]
41
+ # class ReversibleMigrationExample < ActiveRecord::Migration[7.1]
42
42
  # def up
43
43
  # create_table :distributors do |t|
44
44
  # t.string :zipcode
@@ -63,7 +63,7 @@ module ActiveRecord
63
63
  #
64
64
  # 2. Use the #reversible method in <tt>#change</tt> method:
65
65
  #
66
- # class ReversibleMigrationExample < ActiveRecord::Migration[7.0]
66
+ # class ReversibleMigrationExample < ActiveRecord::Migration[7.1]
67
67
  # def change
68
68
  # create_table :distributors do |t|
69
69
  # t.string :zipcode
@@ -137,32 +137,38 @@ module ActiveRecord
137
137
  ActiveRecord::Tasks::DatabaseTasks.migrate
138
138
 
139
139
  if ActiveRecord.dump_schema_after_migration
140
- ActiveRecord::Tasks::DatabaseTasks.dump_schema(
141
- ActiveRecord::Base.connection_db_config
142
- )
140
+ connection = ActiveRecord::Tasks::DatabaseTasks.migration_connection
141
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema(connection.pool.db_config)
143
142
  end
144
143
  end
145
144
 
146
- def initialize(message = nil)
147
- super(message || detailed_migration_message)
145
+ def initialize(message = nil, pending_migrations: nil)
146
+ if pending_migrations.nil?
147
+ connection = ActiveRecord::Tasks::DatabaseTasks.migration_connection
148
+ pending_migrations = connection.migration_context.open.pending_migrations
149
+ end
150
+
151
+ super(message || detailed_migration_message(pending_migrations))
148
152
  end
149
153
 
150
154
  private
151
- def detailed_migration_message
155
+ def detailed_migration_message(pending_migrations)
152
156
  message = "Migrations are pending. To resolve this issue, run:\n\n bin/rails db:migrate"
153
- message += " RAILS_ENV=#{::Rails.env}" if defined?(Rails.env)
157
+ message += " RAILS_ENV=#{::Rails.env}" if defined?(Rails.env) && !Rails.env.local?
154
158
  message += "\n\n"
155
159
 
156
- pending_migrations = ActiveRecord::Base.connection.migration_context.open.pending_migrations
157
-
158
160
  message += "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}\n\n"
159
161
 
160
162
  pending_migrations.each do |pending_migration|
161
- message += "#{pending_migration.basename}\n"
163
+ message += "#{pending_migration.filename}\n"
162
164
  end
163
165
 
164
166
  message
165
167
  end
168
+
169
+ def connection
170
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection
171
+ end
166
172
  end
167
173
 
168
174
  class ConcurrentMigrationError < MigrationError # :nodoc:
@@ -228,7 +234,7 @@ module ActiveRecord
228
234
  #
229
235
  # Example of a simple migration:
230
236
  #
231
- # class AddSsl < ActiveRecord::Migration[7.0]
237
+ # class AddSsl < ActiveRecord::Migration[7.1]
232
238
  # def up
233
239
  # add_column :accounts, :ssl_enabled, :boolean, default: true
234
240
  # end
@@ -248,7 +254,7 @@ module ActiveRecord
248
254
  #
249
255
  # Example of a more complex migration that also needs to initialize data:
250
256
  #
251
- # class AddSystemSettings < ActiveRecord::Migration[7.0]
257
+ # class AddSystemSettings < ActiveRecord::Migration[7.1]
252
258
  # def up
253
259
  # create_table :system_settings do |t|
254
260
  # t.string :name
@@ -356,12 +362,12 @@ module ActiveRecord
356
362
  # == Irreversible transformations
357
363
  #
358
364
  # Some transformations are destructive in a manner that cannot be reversed.
359
- # Migrations of that kind should raise an <tt>ActiveRecord::IrreversibleMigration</tt>
365
+ # Migrations of that kind should raise an ActiveRecord::IrreversibleMigration
360
366
  # exception in their +down+ method.
361
367
  #
362
- # == Running migrations from within Rails
368
+ # == Running migrations from within \Rails
363
369
  #
364
- # The Rails package has several tools to help create and apply migrations.
370
+ # The \Rails package has several tools to help create and apply migrations.
365
371
  #
366
372
  # To generate a new migration, you can use
367
373
  # bin/rails generate migration MyNewMigration
@@ -376,7 +382,7 @@ module ActiveRecord
376
382
  # bin/rails generate migration add_fieldname_to_tablename fieldname:string
377
383
  #
378
384
  # This will generate the file <tt>timestamp_add_fieldname_to_tablename.rb</tt>, which will look like this:
379
- # class AddFieldnameToTablename < ActiveRecord::Migration[7.0]
385
+ # class AddFieldnameToTablename < ActiveRecord::Migration[7.1]
380
386
  # def change
381
387
  # add_column :tablenames, :fieldname, :string
382
388
  # end
@@ -395,14 +401,14 @@ module ActiveRecord
395
401
  # wish to rollback last few migrations. <tt>bin/rails db:rollback STEP=2</tt> will rollback
396
402
  # the latest two migrations.
397
403
  #
398
- # If any of the migrations throw an <tt>ActiveRecord::IrreversibleMigration</tt> exception,
404
+ # If any of the migrations throw an ActiveRecord::IrreversibleMigration exception,
399
405
  # that step will fail and you'll have some manual work to do.
400
406
  #
401
407
  # == More examples
402
408
  #
403
409
  # Not all migrations change the schema. Some just fix the data:
404
410
  #
405
- # class RemoveEmptyTags < ActiveRecord::Migration[7.0]
411
+ # class RemoveEmptyTags < ActiveRecord::Migration[7.1]
406
412
  # def up
407
413
  # Tag.all.each { |tag| tag.destroy if tag.pages.empty? }
408
414
  # end
@@ -415,7 +421,7 @@ module ActiveRecord
415
421
  #
416
422
  # Others remove columns when they migrate up instead of down:
417
423
  #
418
- # class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[7.0]
424
+ # class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[7.1]
419
425
  # def up
420
426
  # remove_column :items, :incomplete_items_count
421
427
  # remove_column :items, :completed_items_count
@@ -429,7 +435,7 @@ module ActiveRecord
429
435
  #
430
436
  # And sometimes you need to do something in SQL not abstracted directly by migrations:
431
437
  #
432
- # class MakeJoinUnique < ActiveRecord::Migration[7.0]
438
+ # class MakeJoinUnique < ActiveRecord::Migration[7.1]
433
439
  # def up
434
440
  # execute "ALTER TABLE `pages_linked_pages` ADD UNIQUE `page_id_linked_page_id` (`page_id`,`linked_page_id`)"
435
441
  # end
@@ -446,7 +452,7 @@ module ActiveRecord
446
452
  # <tt>Base#reset_column_information</tt> in order to ensure that the model has the
447
453
  # latest column data from after the new column was added. Example:
448
454
  #
449
- # class AddPeopleSalary < ActiveRecord::Migration[7.0]
455
+ # class AddPeopleSalary < ActiveRecord::Migration[7.1]
450
456
  # def up
451
457
  # add_column :people, :salary, :integer
452
458
  # Person.reset_column_information
@@ -482,7 +488,7 @@ module ActiveRecord
482
488
  #
483
489
  # == Timestamped Migrations
484
490
  #
485
- # By default, Rails generates migrations that look like:
491
+ # By default, \Rails generates migrations that look like:
486
492
  #
487
493
  # 20080717013526_your_migration_name.rb
488
494
  #
@@ -504,7 +510,7 @@ module ActiveRecord
504
510
  # To define a reversible migration, define the +change+ method in your
505
511
  # migration like this:
506
512
  #
507
- # class TenderloveMigration < ActiveRecord::Migration[7.0]
513
+ # class TenderloveMigration < ActiveRecord::Migration[7.1]
508
514
  # def change
509
515
  # create_table(:horses) do |t|
510
516
  # t.column :content, :text
@@ -521,11 +527,11 @@ module ActiveRecord
521
527
  # as before.
522
528
  #
523
529
  # If a command cannot be reversed, an
524
- # <tt>ActiveRecord::IrreversibleMigration</tt> exception will be raised when
530
+ # ActiveRecord::IrreversibleMigration exception will be raised when
525
531
  # the migration is moving down.
526
532
  #
527
533
  # For a list of commands that are reversible, please see
528
- # <tt>ActiveRecord::Migration::CommandRecorder</tt>.
534
+ # +ActiveRecord::Migration::CommandRecorder+.
529
535
  #
530
536
  # == Transactional Migrations
531
537
  #
@@ -534,7 +540,7 @@ module ActiveRecord
534
540
  # can't execute inside a transaction though, and for these situations
535
541
  # you can turn the automatic transactions off.
536
542
  #
537
- # class ChangeEnum < ActiveRecord::Migration[7.0]
543
+ # class ChangeEnum < ActiveRecord::Migration[7.1]
538
544
  # disable_ddl_transaction!
539
545
  #
540
546
  # def up
@@ -548,6 +554,8 @@ module ActiveRecord
548
554
  autoload :CommandRecorder, "active_record/migration/command_recorder"
549
555
  autoload :Compatibility, "active_record/migration/compatibility"
550
556
  autoload :JoinTable, "active_record/migration/join_table"
557
+ autoload :ExecutionStrategy, "active_record/migration/execution_strategy"
558
+ autoload :DefaultStrategy, "active_record/migration/default_strategy"
551
559
 
552
560
  # This must be defined before the inherited hook, below
553
561
  class Current < Migration # :nodoc:
@@ -610,6 +618,13 @@ module ActiveRecord
610
618
 
611
619
  MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/ # :nodoc:
612
620
 
621
+ def self.valid_version_format?(version_string) # :nodoc:
622
+ [
623
+ MigrationFilenameRegexp,
624
+ /\A\d(_?\d)*\z/ # integer with optional underscores
625
+ ].any? { |pattern| pattern.match?(version_string) }
626
+ end
627
+
613
628
  # This class is used to verify that all migrations have been run before
614
629
  # loading a web page if <tt>config.active_record.migration_error</tt> is set to +:page_load+.
615
630
  class CheckPending
@@ -624,7 +639,7 @@ module ActiveRecord
624
639
  @mutex.synchronize do
625
640
  @watcher ||= build_watcher do
626
641
  @needs_check = true
627
- ActiveRecord::Migration.check_pending!(connection)
642
+ ActiveRecord::Migration.check_pending_migrations
628
643
  @needs_check = false
629
644
  end
630
645
 
@@ -640,12 +655,14 @@ module ActiveRecord
640
655
 
641
656
  private
642
657
  def build_watcher(&block)
643
- paths = Array(connection.migration_context.migrations_paths)
658
+ current_environment = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
659
+ all_configs = ActiveRecord::Base.configurations.configs_for(env_name: current_environment)
660
+ paths = all_configs.flat_map { |config| config.migrations_paths || Migrator.migrations_paths }.uniq
644
661
  @file_watcher.new([], paths.index_with(["rb"]), &block)
645
662
  end
646
663
 
647
664
  def connection
648
- ActiveRecord::Base.connection
665
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection
649
666
  end
650
667
  end
651
668
 
@@ -657,32 +674,53 @@ module ActiveRecord
657
674
  delegate || superclass.nearest_delegate
658
675
  end
659
676
 
660
- # Raises <tt>ActiveRecord::PendingMigrationError</tt> error if any migrations are pending.
661
- def check_pending!(connection = Base.connection)
662
- raise ActiveRecord::PendingMigrationError if connection.migration_context.needs_migration?
677
+ # Raises ActiveRecord::PendingMigrationError error if any migrations are pending.
678
+ #
679
+ # This is deprecated in favor of +check_all_pending!+
680
+ def check_pending!(connection = ActiveRecord::Tasks::DatabaseTasks.migration_connection)
681
+ ActiveRecord.deprecator.warn(<<-MSG.squish)
682
+ The `check_pending!` method is deprecated in favor of `check_all_pending!`. The
683
+ new implementation will loop through all available database configurations and find
684
+ pending migrations. The prior implementation did not permit this.
685
+ MSG
686
+
687
+ pending_migrations = connection.migration_context.open.pending_migrations
688
+
689
+ if pending_migrations.any?
690
+ raise ActiveRecord::PendingMigrationError.new(pending_migrations: pending_migrations)
691
+ end
663
692
  end
664
693
 
665
- def load_schema_if_pending!
666
- current_db_config = Base.connection_db_config
667
- all_configs = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env)
694
+ # Raises ActiveRecord::PendingMigrationError error if any migrations are pending
695
+ # for all database configurations in an environment.
696
+ def check_all_pending!
697
+ pending_migrations = []
698
+
699
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: env) do |connection|
700
+ if pending = connection.migration_context.open.pending_migrations
701
+ pending_migrations << pending
702
+ end
703
+ end
704
+
705
+ migrations = pending_migrations.flatten
668
706
 
669
- needs_update = !all_configs.all? do |db_config|
670
- Tasks::DatabaseTasks.schema_up_to_date?(db_config, ActiveRecord.schema_format)
707
+ if migrations.any?
708
+ raise ActiveRecord::PendingMigrationError.new(pending_migrations: migrations)
671
709
  end
710
+ end
672
711
 
673
- if needs_update
712
+ def load_schema_if_pending!
713
+ if any_schema_needs_update?
674
714
  # Roundtrip to Rake to allow plugins to hook into database initialization.
675
715
  root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
716
+
676
717
  FileUtils.cd(root) do
677
- Base.clear_all_connections!
718
+ Base.connection_handler.clear_all_connections!(:all)
678
719
  system("bin/rails db:test:prepare")
679
720
  end
680
721
  end
681
722
 
682
- # Establish a new connection, the old database may be gone (db:test:prepare uses purge)
683
- Base.establish_connection(current_db_config)
684
-
685
- check_pending!
723
+ check_pending_migrations
686
724
  end
687
725
 
688
726
  def maintain_test_schema! # :nodoc:
@@ -707,6 +745,41 @@ module ActiveRecord
707
745
  def disable_ddl_transaction!
708
746
  @disable_ddl_transaction = true
709
747
  end
748
+
749
+ def check_pending_migrations # :nodoc:
750
+ migrations = pending_migrations
751
+
752
+ if migrations.any?
753
+ raise ActiveRecord::PendingMigrationError.new(pending_migrations: migrations)
754
+ end
755
+ end
756
+
757
+ private
758
+ def any_schema_needs_update?
759
+ !db_configs_in_current_env.all? do |db_config|
760
+ Tasks::DatabaseTasks.schema_up_to_date?(db_config, ActiveRecord.schema_format)
761
+ end
762
+ end
763
+
764
+ def db_configs_in_current_env
765
+ ActiveRecord::Base.configurations.configs_for(env_name: env)
766
+ end
767
+
768
+ def pending_migrations
769
+ pending_migrations = []
770
+
771
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: env) do |connection|
772
+ if pending = connection.migration_context.open.pending_migrations
773
+ pending_migrations << pending
774
+ end
775
+ end
776
+
777
+ pending_migrations.flatten
778
+ end
779
+
780
+ def env
781
+ ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
782
+ end
710
783
  end
711
784
 
712
785
  def disable_ddl_transaction # :nodoc:
@@ -722,6 +795,10 @@ module ActiveRecord
722
795
  @connection = nil
723
796
  end
724
797
 
798
+ def execution_strategy
799
+ @execution_strategy ||= ActiveRecord.migration_strategy.new(self)
800
+ end
801
+
725
802
  self.verbose = true
726
803
  # instantiate the delegate object after initialize is defined
727
804
  self.delegate = new
@@ -733,7 +810,7 @@ module ActiveRecord
733
810
  # and create the table 'apples' on the way up, and the reverse
734
811
  # on the way down.
735
812
  #
736
- # class FixTLMigration < ActiveRecord::Migration[7.0]
813
+ # class FixTLMigration < ActiveRecord::Migration[7.1]
737
814
  # def change
738
815
  # revert do
739
816
  # create_table(:horses) do |t|
@@ -752,7 +829,7 @@ module ActiveRecord
752
829
  #
753
830
  # require_relative "20121212123456_tenderlove_migration"
754
831
  #
755
- # class FixupTLMigration < ActiveRecord::Migration[7.0]
832
+ # class FixupTLMigration < ActiveRecord::Migration[7.1]
756
833
  # def change
757
834
  # revert TenderloveMigration
758
835
  #
@@ -803,7 +880,7 @@ module ActiveRecord
803
880
  # when the three columns 'first_name', 'last_name' and 'full_name' exist,
804
881
  # even when migrating down:
805
882
  #
806
- # class SplitNameMigration < ActiveRecord::Migration[7.0]
883
+ # class SplitNameMigration < ActiveRecord::Migration[7.1]
807
884
  # def change
808
885
  # add_column :users, :first_name, :string
809
886
  # add_column :users, :last_name, :string
@@ -831,7 +908,7 @@ module ActiveRecord
831
908
  # In the following example, the new column +published+ will be given
832
909
  # the value +true+ for all existing records.
833
910
  #
834
- # class AddPublishedToPosts < ActiveRecord::Migration[7.0]
911
+ # class AddPublishedToPosts < ActiveRecord::Migration[7.1]
835
912
  # def change
836
913
  # add_column :posts, :published, :boolean, default: false
837
914
  # up_only do
@@ -884,7 +961,7 @@ module ActiveRecord
884
961
  end
885
962
 
886
963
  time = nil
887
- ActiveRecord::Base.connection_pool.with_connection do |conn|
964
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection.pool.with_connection do |conn|
888
965
  time = Benchmark.measure do
889
966
  exec_migration(conn, direction)
890
967
  end
@@ -909,6 +986,7 @@ module ActiveRecord
909
986
  end
910
987
  ensure
911
988
  @connection = nil
989
+ @execution_strategy = nil
912
990
  end
913
991
 
914
992
  def write(text = "")
@@ -947,7 +1025,7 @@ module ActiveRecord
947
1025
  end
948
1026
 
949
1027
  def connection
950
- @connection || ActiveRecord::Base.connection
1028
+ @connection || ActiveRecord::Tasks::DatabaseTasks.migration_connection
951
1029
  end
952
1030
 
953
1031
  def method_missing(method, *arguments, &block)
@@ -961,22 +1039,23 @@ module ActiveRecord
961
1039
  end
962
1040
  end
963
1041
  end
964
- return super unless connection.respond_to?(method)
965
- connection.send(method, *arguments, &block)
1042
+ return super unless execution_strategy.respond_to?(method)
1043
+ execution_strategy.send(method, *arguments, &block)
966
1044
  end
967
1045
  end
968
1046
  ruby2_keywords(:method_missing)
969
1047
 
970
1048
  def copy(destination, sources, options = {})
971
1049
  copied = []
972
- schema_migration = options[:schema_migration] || ActiveRecord::SchemaMigration
973
1050
 
974
1051
  FileUtils.mkdir_p(destination) unless File.exist?(destination)
1052
+ schema_migration = SchemaMigration::NullSchemaMigration.new
1053
+ internal_metadata = InternalMetadata::NullInternalMetadata.new
975
1054
 
976
- destination_migrations = ActiveRecord::MigrationContext.new(destination, schema_migration).migrations
1055
+ destination_migrations = ActiveRecord::MigrationContext.new(destination, schema_migration, internal_metadata).migrations
977
1056
  last = destination_migrations.last
978
1057
  sources.each do |scope, path|
979
- source_migrations = ActiveRecord::MigrationContext.new(path, schema_migration).migrations
1058
+ source_migrations = ActiveRecord::MigrationContext.new(path, schema_migration, internal_metadata).migrations
980
1059
 
981
1060
  source_migrations.each do |migration|
982
1061
  source = File.binread(migration.filename)
@@ -1037,7 +1116,7 @@ module ActiveRecord
1037
1116
  if ActiveRecord.timestamped_migrations
1038
1117
  [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % number].max
1039
1118
  else
1040
- SchemaMigration.normalize_migration_number(number)
1119
+ "%.3d" % number.to_i
1041
1120
  end
1042
1121
  end
1043
1122
 
@@ -1107,19 +1186,44 @@ module ActiveRecord
1107
1186
  end
1108
1187
  end
1109
1188
 
1189
+ # = \Migration \Context
1190
+ #
1110
1191
  # MigrationContext sets the context in which a migration is run.
1111
1192
  #
1112
1193
  # A migration context requires the path to the migrations is set
1113
1194
  # in the +migrations_paths+ parameter. Optionally a +schema_migration+
1114
- # class can be provided. For most applications, +SchemaMigration+ is
1115
- # sufficient. Multiple database applications need a +SchemaMigration+
1116
- # per primary database.
1195
+ # class can be provided. Multiple database applications will instantiate
1196
+ # a +SchemaMigration+ object per database. From the Rake tasks, \Rails will
1197
+ # handle this for you.
1117
1198
  class MigrationContext
1118
- attr_reader :migrations_paths, :schema_migration
1199
+ attr_reader :migrations_paths, :schema_migration, :internal_metadata
1200
+
1201
+ def initialize(migrations_paths, schema_migration = nil, internal_metadata = nil)
1202
+ if schema_migration == SchemaMigration
1203
+ ActiveRecord.deprecator.warn(<<-MSG.squish)
1204
+ SchemaMigration no longer inherits from ActiveRecord::Base. If you want
1205
+ to use the default connection, remove this argument. If you want to use a
1206
+ specific connection, instantiate MigrationContext with the connection's schema
1207
+ migration, for example `MigrationContext.new(path, Dog.connection.schema_migration)`.
1208
+ MSG
1209
+
1210
+ schema_migration = nil
1211
+ end
1212
+
1213
+ if internal_metadata == InternalMetadata
1214
+ ActiveRecord.deprecator.warn(<<-MSG.squish)
1215
+ SchemaMigration no longer inherits from ActiveRecord::Base. If you want
1216
+ to use the default connection, remove this argument. If you want to use a
1217
+ specific connection, instantiate MigrationContext with the connection's internal
1218
+ metadata, for example `MigrationContext.new(path, nil, Dog.connection.internal_metadata)`.
1219
+ MSG
1220
+
1221
+ internal_metadata = nil
1222
+ end
1119
1223
 
1120
- def initialize(migrations_paths, schema_migration = SchemaMigration)
1121
1224
  @migrations_paths = migrations_paths
1122
- @schema_migration = schema_migration
1225
+ @schema_migration = schema_migration || SchemaMigration.new(connection)
1226
+ @internal_metadata = internal_metadata || InternalMetadata.new(connection)
1123
1227
  end
1124
1228
 
1125
1229
  # Runs the migrations in the +migrations_path+.
@@ -1163,7 +1267,7 @@ module ActiveRecord
1163
1267
  migrations
1164
1268
  end
1165
1269
 
1166
- Migrator.new(:up, selected_migrations, schema_migration, target_version).migrate
1270
+ Migrator.new(:up, selected_migrations, schema_migration, internal_metadata, target_version).migrate
1167
1271
  end
1168
1272
 
1169
1273
  def down(target_version = nil, &block) # :nodoc:
@@ -1173,20 +1277,20 @@ module ActiveRecord
1173
1277
  migrations
1174
1278
  end
1175
1279
 
1176
- Migrator.new(:down, selected_migrations, schema_migration, target_version).migrate
1280
+ Migrator.new(:down, selected_migrations, schema_migration, internal_metadata, target_version).migrate
1177
1281
  end
1178
1282
 
1179
1283
  def run(direction, target_version) # :nodoc:
1180
- Migrator.new(direction, migrations, schema_migration, target_version).run
1284
+ Migrator.new(direction, migrations, schema_migration, internal_metadata, target_version).run
1181
1285
  end
1182
1286
 
1183
1287
  def open # :nodoc:
1184
- Migrator.new(:up, migrations, schema_migration)
1288
+ Migrator.new(:up, migrations, schema_migration, internal_metadata)
1185
1289
  end
1186
1290
 
1187
1291
  def get_all_versions # :nodoc:
1188
1292
  if schema_migration.table_exists?
1189
- schema_migration.all_versions.map(&:to_i)
1293
+ schema_migration.integer_versions
1190
1294
  else
1191
1295
  []
1192
1296
  end
@@ -1245,16 +1349,20 @@ module ActiveRecord
1245
1349
  end
1246
1350
 
1247
1351
  def last_stored_environment # :nodoc:
1248
- return nil unless ActiveRecord::InternalMetadata.enabled?
1352
+ return nil unless connection.internal_metadata.enabled?
1249
1353
  return nil if current_version == 0
1250
- raise NoEnvironmentInSchemaError unless ActiveRecord::InternalMetadata.table_exists?
1354
+ raise NoEnvironmentInSchemaError unless connection.internal_metadata.table_exists?
1251
1355
 
1252
- environment = ActiveRecord::InternalMetadata[:environment]
1356
+ environment = connection.internal_metadata[:environment]
1253
1357
  raise NoEnvironmentInSchemaError unless environment
1254
1358
  environment
1255
1359
  end
1256
1360
 
1257
1361
  private
1362
+ def connection
1363
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection
1364
+ end
1365
+
1258
1366
  def migration_files
1259
1367
  paths = Array(migrations_paths)
1260
1368
  Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
@@ -1265,7 +1373,7 @@ module ActiveRecord
1265
1373
  end
1266
1374
 
1267
1375
  def move(direction, steps)
1268
- migrator = Migrator.new(direction, migrations, schema_migration)
1376
+ migrator = Migrator.new(direction, migrations, schema_migration, internal_metadata)
1269
1377
 
1270
1378
  if current_version != 0 && !migrator.current_migration
1271
1379
  raise UnknownMigrationVersionError.new(current_version)
@@ -1290,23 +1398,28 @@ module ActiveRecord
1290
1398
 
1291
1399
  # For cases where a table doesn't exist like loading from schema cache
1292
1400
  def current_version
1293
- MigrationContext.new(migrations_paths, SchemaMigration).current_version
1401
+ connection = ActiveRecord::Tasks::DatabaseTasks.migration_connection
1402
+ schema_migration = SchemaMigration.new(connection)
1403
+ internal_metadata = InternalMetadata.new(connection)
1404
+
1405
+ MigrationContext.new(migrations_paths, schema_migration, internal_metadata).current_version
1294
1406
  end
1295
1407
  end
1296
1408
 
1297
1409
  self.migrations_paths = ["db/migrate"]
1298
1410
 
1299
- def initialize(direction, migrations, schema_migration, target_version = nil)
1411
+ def initialize(direction, migrations, schema_migration, internal_metadata, target_version = nil)
1300
1412
  @direction = direction
1301
1413
  @target_version = target_version
1302
1414
  @migrated_versions = nil
1303
1415
  @migrations = migrations
1304
1416
  @schema_migration = schema_migration
1417
+ @internal_metadata = internal_metadata
1305
1418
 
1306
1419
  validate(@migrations)
1307
1420
 
1308
1421
  @schema_migration.create_table
1309
- ActiveRecord::InternalMetadata.create_table
1422
+ @internal_metadata.create_table
1310
1423
  end
1311
1424
 
1312
1425
  def current_version
@@ -1359,18 +1472,21 @@ module ActiveRecord
1359
1472
  end
1360
1473
 
1361
1474
  def load_migrated
1362
- @migrated_versions = Set.new(@schema_migration.all_versions.map(&:to_i))
1475
+ @migrated_versions = Set.new(@schema_migration.integer_versions)
1363
1476
  end
1364
1477
 
1365
1478
  private
1479
+ def connection
1480
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection
1481
+ end
1482
+
1366
1483
  # Used for running a specific migration.
1367
1484
  def run_without_lock
1368
1485
  migration = migrations.detect { |m| m.version == @target_version }
1369
1486
  raise UnknownMigrationVersionError.new(@target_version) if migration.nil?
1370
- result = execute_migration_in_transaction(migration)
1371
1487
 
1372
1488
  record_environment
1373
- result
1489
+ execute_migration_in_transaction(migration)
1374
1490
  end
1375
1491
 
1376
1492
  # Used for running multiple migrations up to or down to a certain value.
@@ -1379,15 +1495,15 @@ module ActiveRecord
1379
1495
  raise UnknownMigrationVersionError.new(@target_version)
1380
1496
  end
1381
1497
 
1382
- result = runnable.each(&method(:execute_migration_in_transaction))
1383
1498
  record_environment
1384
- result
1499
+ runnable.each(&method(:execute_migration_in_transaction))
1385
1500
  end
1386
1501
 
1387
1502
  # Stores the current environment in the database.
1388
1503
  def record_environment
1389
1504
  return if down?
1390
- ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Base.connection.pool.db_config.env_name
1505
+
1506
+ @internal_metadata[:environment] = connection.pool.db_config.env_name
1391
1507
  end
1392
1508
 
1393
1509
  def ran?(migration)
@@ -1439,10 +1555,10 @@ module ActiveRecord
1439
1555
  def record_version_state_after_migrating(version)
1440
1556
  if down?
1441
1557
  migrated.delete(version)
1442
- @schema_migration.delete_by(version: version.to_s)
1558
+ @schema_migration.delete_version(version.to_s)
1443
1559
  else
1444
1560
  migrated << version
1445
- @schema_migration.create!(version: version.to_s)
1561
+ @schema_migration.create_version(version.to_s)
1446
1562
  end
1447
1563
  end
1448
1564
 
@@ -1457,50 +1573,38 @@ module ActiveRecord
1457
1573
  # Wrap the migration in a transaction only if supported by the adapter.
1458
1574
  def ddl_transaction(migration, &block)
1459
1575
  if use_transaction?(migration)
1460
- Base.transaction(&block)
1576
+ connection.transaction(&block)
1461
1577
  else
1462
1578
  yield
1463
1579
  end
1464
1580
  end
1465
1581
 
1466
1582
  def use_transaction?(migration)
1467
- !migration.disable_ddl_transaction && Base.connection.supports_ddl_transactions?
1583
+ !migration.disable_ddl_transaction && connection.supports_ddl_transactions?
1468
1584
  end
1469
1585
 
1470
1586
  def use_advisory_lock?
1471
- Base.connection.advisory_locks_enabled?
1587
+ connection.advisory_locks_enabled?
1472
1588
  end
1473
1589
 
1474
1590
  def with_advisory_lock
1475
1591
  lock_id = generate_migrator_advisory_lock_id
1476
1592
 
1477
- with_advisory_lock_connection do |connection|
1478
- got_lock = connection.get_advisory_lock(lock_id)
1479
- raise ConcurrentMigrationError unless got_lock
1480
- load_migrated # reload schema_migrations to be sure it wasn't changed by another process before we got the lock
1481
- yield
1482
- ensure
1483
- if got_lock && !connection.release_advisory_lock(lock_id)
1484
- raise ConcurrentMigrationError.new(
1485
- ConcurrentMigrationError::RELEASE_LOCK_FAILED_MESSAGE
1486
- )
1487
- end
1488
- end
1489
- end
1490
-
1491
- def with_advisory_lock_connection(&block)
1492
- pool = ActiveRecord::ConnectionAdapters::ConnectionHandler.new.establish_connection(
1493
- ActiveRecord::Base.connection_db_config
1494
- )
1495
-
1496
- pool.with_connection(&block)
1593
+ got_lock = connection.get_advisory_lock(lock_id)
1594
+ raise ConcurrentMigrationError unless got_lock
1595
+ load_migrated # reload schema_migrations to be sure it wasn't changed by another process before we got the lock
1596
+ yield
1497
1597
  ensure
1498
- pool&.disconnect!
1598
+ if got_lock && !connection.release_advisory_lock(lock_id)
1599
+ raise ConcurrentMigrationError.new(
1600
+ ConcurrentMigrationError::RELEASE_LOCK_FAILED_MESSAGE
1601
+ )
1602
+ end
1499
1603
  end
1500
1604
 
1501
1605
  MIGRATOR_SALT = 2053462845
1502
1606
  def generate_migrator_advisory_lock_id
1503
- db_name_hash = Zlib.crc32(Base.connection.current_database)
1607
+ db_name_hash = Zlib.crc32(connection.current_database)
1504
1608
  MIGRATOR_SALT * db_name_hash
1505
1609
  end
1506
1610
  end