activerecord 7.0.6 → 7.1.1

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 (231) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1424 -1390
  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 +16 -10
  15. data/lib/active_record/associations/collection_proxy.rb +20 -10
  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 -7
  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 +13 -10
  23. data/lib/active_record/associations/singular_association.rb +6 -8
  24. data/lib/active_record/associations/through_association.rb +22 -11
  25. data/lib/active_record/associations.rb +295 -199
  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 +60 -18
  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 +128 -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 -124
  54. data/lib/active_record/connection_adapters/abstract/transaction.rb +287 -58
  55. data/lib/active_record/connection_adapters/abstract_adapter.rb +496 -102
  56. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +214 -113
  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 +23 -144
  60. data/lib/active_record/connection_adapters/mysql/quoting.rb +21 -14
  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 +18 -13
  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 +14 -3
  70. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +71 -40
  71. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +11 -2
  72. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +1 -1
  73. data/lib/active_record/connection_adapters/postgresql/quoting.rb +15 -8
  74. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +3 -9
  75. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -6
  76. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +131 -2
  77. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +53 -0
  78. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +349 -55
  79. data/lib/active_record/connection_adapters/postgresql_adapter.rb +338 -176
  80. data/lib/active_record/connection_adapters/schema_cache.rb +287 -59
  81. data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
  82. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +45 -39
  83. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +9 -5
  84. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +7 -0
  85. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +28 -9
  86. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +210 -83
  87. data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
  88. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +98 -0
  89. data/lib/active_record/connection_adapters/trilogy_adapter.rb +254 -0
  90. data/lib/active_record/connection_adapters.rb +3 -1
  91. data/lib/active_record/connection_handling.rb +71 -94
  92. data/lib/active_record/core.rb +136 -148
  93. data/lib/active_record/counter_cache.rb +46 -25
  94. data/lib/active_record/database_configurations/database_config.rb +9 -3
  95. data/lib/active_record/database_configurations/hash_config.rb +22 -12
  96. data/lib/active_record/database_configurations/url_config.rb +17 -11
  97. data/lib/active_record/database_configurations.rb +86 -33
  98. data/lib/active_record/delegated_type.rb +8 -3
  99. data/lib/active_record/deprecator.rb +7 -0
  100. data/lib/active_record/destroy_association_async_job.rb +2 -0
  101. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  102. data/lib/active_record/encryption/cipher/aes256_gcm.rb +4 -1
  103. data/lib/active_record/encryption/config.rb +25 -1
  104. data/lib/active_record/encryption/configurable.rb +12 -19
  105. data/lib/active_record/encryption/context.rb +10 -3
  106. data/lib/active_record/encryption/contexts.rb +5 -1
  107. data/lib/active_record/encryption/derived_secret_key_provider.rb +8 -2
  108. data/lib/active_record/encryption/encryptable_record.rb +36 -18
  109. data/lib/active_record/encryption/encrypted_attribute_type.rb +17 -6
  110. data/lib/active_record/encryption/extended_deterministic_queries.rb +66 -54
  111. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +3 -3
  112. data/lib/active_record/encryption/key_generator.rb +12 -1
  113. data/lib/active_record/encryption/message_serializer.rb +2 -0
  114. data/lib/active_record/encryption/properties.rb +3 -3
  115. data/lib/active_record/encryption/scheme.rb +19 -22
  116. data/lib/active_record/encryption.rb +1 -0
  117. data/lib/active_record/enum.rb +113 -26
  118. data/lib/active_record/errors.rb +108 -15
  119. data/lib/active_record/explain.rb +23 -3
  120. data/lib/active_record/fixture_set/model_metadata.rb +14 -4
  121. data/lib/active_record/fixture_set/render_context.rb +2 -0
  122. data/lib/active_record/fixture_set/table_row.rb +29 -8
  123. data/lib/active_record/fixtures.rb +119 -71
  124. data/lib/active_record/future_result.rb +30 -5
  125. data/lib/active_record/gem_version.rb +3 -3
  126. data/lib/active_record/inheritance.rb +30 -16
  127. data/lib/active_record/insert_all.rb +55 -8
  128. data/lib/active_record/integration.rb +8 -8
  129. data/lib/active_record/internal_metadata.rb +120 -30
  130. data/lib/active_record/locking/pessimistic.rb +5 -2
  131. data/lib/active_record/log_subscriber.rb +29 -12
  132. data/lib/active_record/marshalling.rb +56 -0
  133. data/lib/active_record/message_pack.rb +124 -0
  134. data/lib/active_record/middleware/database_selector/resolver.rb +4 -0
  135. data/lib/active_record/middleware/database_selector.rb +5 -7
  136. data/lib/active_record/middleware/shard_selector.rb +3 -1
  137. data/lib/active_record/migration/command_recorder.rb +104 -5
  138. data/lib/active_record/migration/compatibility.rb +142 -58
  139. data/lib/active_record/migration/default_strategy.rb +23 -0
  140. data/lib/active_record/migration/execution_strategy.rb +19 -0
  141. data/lib/active_record/migration.rb +265 -112
  142. data/lib/active_record/model_schema.rb +60 -40
  143. data/lib/active_record/nested_attributes.rb +21 -3
  144. data/lib/active_record/normalization.rb +159 -0
  145. data/lib/active_record/persistence.rb +187 -35
  146. data/lib/active_record/promise.rb +84 -0
  147. data/lib/active_record/query_cache.rb +3 -21
  148. data/lib/active_record/query_logs.rb +77 -52
  149. data/lib/active_record/query_logs_formatter.rb +41 -0
  150. data/lib/active_record/querying.rb +15 -2
  151. data/lib/active_record/railtie.rb +109 -47
  152. data/lib/active_record/railties/controller_runtime.rb +12 -8
  153. data/lib/active_record/railties/databases.rake +139 -145
  154. data/lib/active_record/railties/job_runtime.rb +23 -0
  155. data/lib/active_record/readonly_attributes.rb +32 -5
  156. data/lib/active_record/reflection.rb +162 -44
  157. data/lib/active_record/relation/batches/batch_enumerator.rb +5 -3
  158. data/lib/active_record/relation/batches.rb +190 -61
  159. data/lib/active_record/relation/calculations.rb +160 -63
  160. data/lib/active_record/relation/delegation.rb +22 -8
  161. data/lib/active_record/relation/finder_methods.rb +77 -16
  162. data/lib/active_record/relation/merger.rb +2 -0
  163. data/lib/active_record/relation/predicate_builder/association_query_value.rb +11 -2
  164. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -6
  165. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  166. data/lib/active_record/relation/predicate_builder.rb +27 -16
  167. data/lib/active_record/relation/query_attribute.rb +25 -1
  168. data/lib/active_record/relation/query_methods.rb +378 -70
  169. data/lib/active_record/relation/spawn_methods.rb +18 -1
  170. data/lib/active_record/relation.rb +76 -35
  171. data/lib/active_record/result.rb +19 -5
  172. data/lib/active_record/runtime_registry.rb +10 -1
  173. data/lib/active_record/sanitization.rb +51 -11
  174. data/lib/active_record/schema.rb +2 -3
  175. data/lib/active_record/schema_dumper.rb +46 -7
  176. data/lib/active_record/schema_migration.rb +68 -33
  177. data/lib/active_record/scoping/default.rb +15 -5
  178. data/lib/active_record/scoping/named.rb +2 -2
  179. data/lib/active_record/scoping.rb +2 -1
  180. data/lib/active_record/secure_password.rb +60 -0
  181. data/lib/active_record/secure_token.rb +21 -3
  182. data/lib/active_record/signed_id.rb +7 -5
  183. data/lib/active_record/store.rb +8 -8
  184. data/lib/active_record/suppressor.rb +3 -1
  185. data/lib/active_record/table_metadata.rb +11 -2
  186. data/lib/active_record/tasks/database_tasks.rb +127 -105
  187. data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
  188. data/lib/active_record/tasks/postgresql_database_tasks.rb +16 -13
  189. data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
  190. data/lib/active_record/test_fixtures.rb +113 -96
  191. data/lib/active_record/timestamp.rb +27 -15
  192. data/lib/active_record/token_for.rb +113 -0
  193. data/lib/active_record/touch_later.rb +11 -6
  194. data/lib/active_record/transactions.rb +39 -13
  195. data/lib/active_record/type/adapter_specific_registry.rb +1 -8
  196. data/lib/active_record/type/internal/timezone.rb +7 -2
  197. data/lib/active_record/type/serialized.rb +4 -0
  198. data/lib/active_record/type/time.rb +4 -0
  199. data/lib/active_record/validations/absence.rb +1 -1
  200. data/lib/active_record/validations/numericality.rb +5 -4
  201. data/lib/active_record/validations/presence.rb +5 -28
  202. data/lib/active_record/validations/uniqueness.rb +47 -2
  203. data/lib/active_record/validations.rb +8 -4
  204. data/lib/active_record/version.rb +1 -1
  205. data/lib/active_record.rb +121 -16
  206. data/lib/arel/errors.rb +10 -0
  207. data/lib/arel/factory_methods.rb +4 -0
  208. data/lib/arel/nodes/and.rb +4 -0
  209. data/lib/arel/nodes/binary.rb +6 -1
  210. data/lib/arel/nodes/bound_sql_literal.rb +61 -0
  211. data/lib/arel/nodes/cte.rb +36 -0
  212. data/lib/arel/nodes/fragments.rb +35 -0
  213. data/lib/arel/nodes/homogeneous_in.rb +0 -8
  214. data/lib/arel/nodes/leading_join.rb +8 -0
  215. data/lib/arel/nodes/node.rb +111 -2
  216. data/lib/arel/nodes/sql_literal.rb +6 -0
  217. data/lib/arel/nodes/table_alias.rb +4 -0
  218. data/lib/arel/nodes.rb +4 -0
  219. data/lib/arel/predications.rb +2 -0
  220. data/lib/arel/table.rb +9 -5
  221. data/lib/arel/visitors/mysql.rb +8 -1
  222. data/lib/arel/visitors/to_sql.rb +81 -17
  223. data/lib/arel/visitors/visitor.rb +2 -2
  224. data/lib/arel.rb +16 -2
  225. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  226. data/lib/rails/generators/active_record/migration.rb +3 -1
  227. data/lib/rails/generators/active_record/model/USAGE +113 -0
  228. data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
  229. metadata +50 -15
  230. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
  231. 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,9 +554,46 @@ 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:
562
+ def create_table(table_name, **options)
563
+ if block_given?
564
+ super { |t| yield compatible_table_definition(t) }
565
+ else
566
+ super
567
+ end
568
+ end
569
+
570
+ def change_table(table_name, **options)
571
+ if block_given?
572
+ super { |t| yield compatible_table_definition(t) }
573
+ else
574
+ super
575
+ end
576
+ end
577
+
578
+ def create_join_table(table_1, table_2, **options)
579
+ if block_given?
580
+ super { |t| yield compatible_table_definition(t) }
581
+ else
582
+ super
583
+ end
584
+ end
585
+
586
+ def drop_table(table_name, **options)
587
+ if block_given?
588
+ super { |t| yield compatible_table_definition(t) }
589
+ else
590
+ super
591
+ end
592
+ end
593
+
594
+ def compatible_table_definition(t)
595
+ t
596
+ end
554
597
  end
555
598
 
556
599
  def self.inherited(subclass) # :nodoc:
@@ -575,6 +618,13 @@ module ActiveRecord
575
618
 
576
619
  MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/ # :nodoc:
577
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
+
578
628
  # This class is used to verify that all migrations have been run before
579
629
  # loading a web page if <tt>config.active_record.migration_error</tt> is set to +:page_load+.
580
630
  class CheckPending
@@ -589,7 +639,7 @@ module ActiveRecord
589
639
  @mutex.synchronize do
590
640
  @watcher ||= build_watcher do
591
641
  @needs_check = true
592
- ActiveRecord::Migration.check_pending!(connection)
642
+ ActiveRecord::Migration.check_pending_migrations
593
643
  @needs_check = false
594
644
  end
595
645
 
@@ -605,12 +655,14 @@ module ActiveRecord
605
655
 
606
656
  private
607
657
  def build_watcher(&block)
608
- 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
609
661
  @file_watcher.new([], paths.index_with(["rb"]), &block)
610
662
  end
611
663
 
612
664
  def connection
613
- ActiveRecord::Base.connection
665
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection
614
666
  end
615
667
  end
616
668
 
@@ -622,32 +674,53 @@ module ActiveRecord
622
674
  delegate || superclass.nearest_delegate
623
675
  end
624
676
 
625
- # Raises <tt>ActiveRecord::PendingMigrationError</tt> error if any migrations are pending.
626
- def check_pending!(connection = Base.connection)
627
- 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
628
692
  end
629
693
 
630
- def load_schema_if_pending!
631
- current_db_config = Base.connection_db_config
632
- 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 = []
633
698
 
634
- needs_update = !all_configs.all? do |db_config|
635
- Tasks::DatabaseTasks.schema_up_to_date?(db_config, ActiveRecord.schema_format)
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
636
703
  end
637
704
 
638
- if needs_update
705
+ migrations = pending_migrations.flatten
706
+
707
+ if migrations.any?
708
+ raise ActiveRecord::PendingMigrationError.new(pending_migrations: migrations)
709
+ end
710
+ end
711
+
712
+ def load_schema_if_pending!
713
+ if any_schema_needs_update?
639
714
  # Roundtrip to Rake to allow plugins to hook into database initialization.
640
715
  root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
716
+
641
717
  FileUtils.cd(root) do
642
- Base.clear_all_connections!
718
+ Base.connection_handler.clear_all_connections!(:all)
643
719
  system("bin/rails db:test:prepare")
644
720
  end
645
721
  end
646
722
 
647
- # Establish a new connection, the old database may be gone (db:test:prepare uses purge)
648
- Base.establish_connection(current_db_config)
649
-
650
- check_pending!
723
+ check_pending_migrations
651
724
  end
652
725
 
653
726
  def maintain_test_schema! # :nodoc:
@@ -672,6 +745,41 @@ module ActiveRecord
672
745
  def disable_ddl_transaction!
673
746
  @disable_ddl_transaction = true
674
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
675
783
  end
676
784
 
677
785
  def disable_ddl_transaction # :nodoc:
@@ -687,6 +795,10 @@ module ActiveRecord
687
795
  @connection = nil
688
796
  end
689
797
 
798
+ def execution_strategy
799
+ @execution_strategy ||= ActiveRecord.migration_strategy.new(self)
800
+ end
801
+
690
802
  self.verbose = true
691
803
  # instantiate the delegate object after initialize is defined
692
804
  self.delegate = new
@@ -698,7 +810,7 @@ module ActiveRecord
698
810
  # and create the table 'apples' on the way up, and the reverse
699
811
  # on the way down.
700
812
  #
701
- # class FixTLMigration < ActiveRecord::Migration[7.0]
813
+ # class FixTLMigration < ActiveRecord::Migration[7.1]
702
814
  # def change
703
815
  # revert do
704
816
  # create_table(:horses) do |t|
@@ -717,7 +829,7 @@ module ActiveRecord
717
829
  #
718
830
  # require_relative "20121212123456_tenderlove_migration"
719
831
  #
720
- # class FixupTLMigration < ActiveRecord::Migration[7.0]
832
+ # class FixupTLMigration < ActiveRecord::Migration[7.1]
721
833
  # def change
722
834
  # revert TenderloveMigration
723
835
  #
@@ -768,7 +880,7 @@ module ActiveRecord
768
880
  # when the three columns 'first_name', 'last_name' and 'full_name' exist,
769
881
  # even when migrating down:
770
882
  #
771
- # class SplitNameMigration < ActiveRecord::Migration[7.0]
883
+ # class SplitNameMigration < ActiveRecord::Migration[7.1]
772
884
  # def change
773
885
  # add_column :users, :first_name, :string
774
886
  # add_column :users, :last_name, :string
@@ -796,7 +908,7 @@ module ActiveRecord
796
908
  # In the following example, the new column +published+ will be given
797
909
  # the value +true+ for all existing records.
798
910
  #
799
- # class AddPublishedToPosts < ActiveRecord::Migration[7.0]
911
+ # class AddPublishedToPosts < ActiveRecord::Migration[7.1]
800
912
  # def change
801
913
  # add_column :posts, :published, :boolean, default: false
802
914
  # up_only do
@@ -849,7 +961,7 @@ module ActiveRecord
849
961
  end
850
962
 
851
963
  time = nil
852
- ActiveRecord::Base.connection_pool.with_connection do |conn|
964
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection.pool.with_connection do |conn|
853
965
  time = Benchmark.measure do
854
966
  exec_migration(conn, direction)
855
967
  end
@@ -874,6 +986,7 @@ module ActiveRecord
874
986
  end
875
987
  ensure
876
988
  @connection = nil
989
+ @execution_strategy = nil
877
990
  end
878
991
 
879
992
  def write(text = "")
@@ -912,13 +1025,11 @@ module ActiveRecord
912
1025
  end
913
1026
 
914
1027
  def connection
915
- @connection || ActiveRecord::Base.connection
1028
+ @connection || ActiveRecord::Tasks::DatabaseTasks.migration_connection
916
1029
  end
917
1030
 
918
1031
  def method_missing(method, *arguments, &block)
919
- arg_list = arguments.map(&:inspect) * ", "
920
-
921
- say_with_time "#{method}(#{arg_list})" do
1032
+ say_with_time "#{method}(#{format_arguments(arguments)})" do
922
1033
  unless connection.respond_to? :revert
923
1034
  unless arguments.empty? || [:execute, :enable_extension, :disable_extension].include?(method)
924
1035
  arguments[0] = proper_table_name(arguments.first, table_name_options)
@@ -928,22 +1039,23 @@ module ActiveRecord
928
1039
  end
929
1040
  end
930
1041
  end
931
- return super unless connection.respond_to?(method)
932
- connection.send(method, *arguments, &block)
1042
+ return super unless execution_strategy.respond_to?(method)
1043
+ execution_strategy.send(method, *arguments, &block)
933
1044
  end
934
1045
  end
935
1046
  ruby2_keywords(:method_missing)
936
1047
 
937
1048
  def copy(destination, sources, options = {})
938
1049
  copied = []
939
- schema_migration = options[:schema_migration] || ActiveRecord::SchemaMigration
940
1050
 
941
1051
  FileUtils.mkdir_p(destination) unless File.exist?(destination)
1052
+ schema_migration = SchemaMigration::NullSchemaMigration.new
1053
+ internal_metadata = InternalMetadata::NullInternalMetadata.new
942
1054
 
943
- destination_migrations = ActiveRecord::MigrationContext.new(destination, schema_migration).migrations
1055
+ destination_migrations = ActiveRecord::MigrationContext.new(destination, schema_migration, internal_metadata).migrations
944
1056
  last = destination_migrations.last
945
1057
  sources.each do |scope, path|
946
- source_migrations = ActiveRecord::MigrationContext.new(path, schema_migration).migrations
1058
+ source_migrations = ActiveRecord::MigrationContext.new(path, schema_migration, internal_metadata).migrations
947
1059
 
948
1060
  source_migrations.each do |migration|
949
1061
  source = File.binread(migration.filename)
@@ -1004,7 +1116,7 @@ module ActiveRecord
1004
1116
  if ActiveRecord.timestamped_migrations
1005
1117
  [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % number].max
1006
1118
  else
1007
- SchemaMigration.normalize_migration_number(number)
1119
+ "%.3d" % number.to_i
1008
1120
  end
1009
1121
  end
1010
1122
 
@@ -1026,6 +1138,22 @@ module ActiveRecord
1026
1138
  end
1027
1139
  end
1028
1140
 
1141
+ def format_arguments(arguments)
1142
+ arg_list = arguments[0...-1].map(&:inspect)
1143
+ last_arg = arguments.last
1144
+ if last_arg.is_a?(Hash)
1145
+ last_arg = last_arg.reject { |k, _v| internal_option?(k) }
1146
+ arg_list << last_arg.inspect unless last_arg.empty?
1147
+ else
1148
+ arg_list << last_arg.inspect
1149
+ end
1150
+ arg_list.join(", ")
1151
+ end
1152
+
1153
+ def internal_option?(option_name)
1154
+ option_name.start_with?("_")
1155
+ end
1156
+
1029
1157
  def command_recorder
1030
1158
  CommandRecorder.new(connection)
1031
1159
  end
@@ -1058,19 +1186,44 @@ module ActiveRecord
1058
1186
  end
1059
1187
  end
1060
1188
 
1189
+ # = \Migration \Context
1190
+ #
1061
1191
  # MigrationContext sets the context in which a migration is run.
1062
1192
  #
1063
1193
  # A migration context requires the path to the migrations is set
1064
1194
  # in the +migrations_paths+ parameter. Optionally a +schema_migration+
1065
- # class can be provided. For most applications, +SchemaMigration+ is
1066
- # sufficient. Multiple database applications need a +SchemaMigration+
1067
- # 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.
1068
1198
  class MigrationContext
1069
- 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
1070
1223
 
1071
- def initialize(migrations_paths, schema_migration = SchemaMigration)
1072
1224
  @migrations_paths = migrations_paths
1073
- @schema_migration = schema_migration
1225
+ @schema_migration = schema_migration || SchemaMigration.new(connection)
1226
+ @internal_metadata = internal_metadata || InternalMetadata.new(connection)
1074
1227
  end
1075
1228
 
1076
1229
  # Runs the migrations in the +migrations_path+.
@@ -1114,7 +1267,7 @@ module ActiveRecord
1114
1267
  migrations
1115
1268
  end
1116
1269
 
1117
- Migrator.new(:up, selected_migrations, schema_migration, target_version).migrate
1270
+ Migrator.new(:up, selected_migrations, schema_migration, internal_metadata, target_version).migrate
1118
1271
  end
1119
1272
 
1120
1273
  def down(target_version = nil, &block) # :nodoc:
@@ -1124,20 +1277,20 @@ module ActiveRecord
1124
1277
  migrations
1125
1278
  end
1126
1279
 
1127
- Migrator.new(:down, selected_migrations, schema_migration, target_version).migrate
1280
+ Migrator.new(:down, selected_migrations, schema_migration, internal_metadata, target_version).migrate
1128
1281
  end
1129
1282
 
1130
1283
  def run(direction, target_version) # :nodoc:
1131
- Migrator.new(direction, migrations, schema_migration, target_version).run
1284
+ Migrator.new(direction, migrations, schema_migration, internal_metadata, target_version).run
1132
1285
  end
1133
1286
 
1134
1287
  def open # :nodoc:
1135
- Migrator.new(:up, migrations, schema_migration)
1288
+ Migrator.new(:up, migrations, schema_migration, internal_metadata)
1136
1289
  end
1137
1290
 
1138
1291
  def get_all_versions # :nodoc:
1139
1292
  if schema_migration.table_exists?
1140
- schema_migration.all_versions.map(&:to_i)
1293
+ schema_migration.integer_versions
1141
1294
  else
1142
1295
  []
1143
1296
  end
@@ -1196,16 +1349,20 @@ module ActiveRecord
1196
1349
  end
1197
1350
 
1198
1351
  def last_stored_environment # :nodoc:
1199
- return nil unless ActiveRecord::InternalMetadata.enabled?
1352
+ return nil unless connection.internal_metadata.enabled?
1200
1353
  return nil if current_version == 0
1201
- raise NoEnvironmentInSchemaError unless ActiveRecord::InternalMetadata.table_exists?
1354
+ raise NoEnvironmentInSchemaError unless connection.internal_metadata.table_exists?
1202
1355
 
1203
- environment = ActiveRecord::InternalMetadata[:environment]
1356
+ environment = connection.internal_metadata[:environment]
1204
1357
  raise NoEnvironmentInSchemaError unless environment
1205
1358
  environment
1206
1359
  end
1207
1360
 
1208
1361
  private
1362
+ def connection
1363
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection
1364
+ end
1365
+
1209
1366
  def migration_files
1210
1367
  paths = Array(migrations_paths)
1211
1368
  Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
@@ -1216,7 +1373,7 @@ module ActiveRecord
1216
1373
  end
1217
1374
 
1218
1375
  def move(direction, steps)
1219
- migrator = Migrator.new(direction, migrations, schema_migration)
1376
+ migrator = Migrator.new(direction, migrations, schema_migration, internal_metadata)
1220
1377
 
1221
1378
  if current_version != 0 && !migrator.current_migration
1222
1379
  raise UnknownMigrationVersionError.new(current_version)
@@ -1241,23 +1398,28 @@ module ActiveRecord
1241
1398
 
1242
1399
  # For cases where a table doesn't exist like loading from schema cache
1243
1400
  def current_version
1244
- 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
1245
1406
  end
1246
1407
  end
1247
1408
 
1248
1409
  self.migrations_paths = ["db/migrate"]
1249
1410
 
1250
- def initialize(direction, migrations, schema_migration, target_version = nil)
1411
+ def initialize(direction, migrations, schema_migration, internal_metadata, target_version = nil)
1251
1412
  @direction = direction
1252
1413
  @target_version = target_version
1253
1414
  @migrated_versions = nil
1254
1415
  @migrations = migrations
1255
1416
  @schema_migration = schema_migration
1417
+ @internal_metadata = internal_metadata
1256
1418
 
1257
1419
  validate(@migrations)
1258
1420
 
1259
1421
  @schema_migration.create_table
1260
- ActiveRecord::InternalMetadata.create_table
1422
+ @internal_metadata.create_table
1261
1423
  end
1262
1424
 
1263
1425
  def current_version
@@ -1310,18 +1472,21 @@ module ActiveRecord
1310
1472
  end
1311
1473
 
1312
1474
  def load_migrated
1313
- @migrated_versions = Set.new(@schema_migration.all_versions.map(&:to_i))
1475
+ @migrated_versions = Set.new(@schema_migration.integer_versions)
1314
1476
  end
1315
1477
 
1316
1478
  private
1479
+ def connection
1480
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection
1481
+ end
1482
+
1317
1483
  # Used for running a specific migration.
1318
1484
  def run_without_lock
1319
1485
  migration = migrations.detect { |m| m.version == @target_version }
1320
1486
  raise UnknownMigrationVersionError.new(@target_version) if migration.nil?
1321
- result = execute_migration_in_transaction(migration)
1322
1487
 
1323
1488
  record_environment
1324
- result
1489
+ execute_migration_in_transaction(migration)
1325
1490
  end
1326
1491
 
1327
1492
  # Used for running multiple migrations up to or down to a certain value.
@@ -1330,15 +1495,15 @@ module ActiveRecord
1330
1495
  raise UnknownMigrationVersionError.new(@target_version)
1331
1496
  end
1332
1497
 
1333
- result = runnable.each(&method(:execute_migration_in_transaction))
1334
1498
  record_environment
1335
- result
1499
+ runnable.each(&method(:execute_migration_in_transaction))
1336
1500
  end
1337
1501
 
1338
1502
  # Stores the current environment in the database.
1339
1503
  def record_environment
1340
1504
  return if down?
1341
- ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Base.connection.pool.db_config.env_name
1505
+
1506
+ @internal_metadata[:environment] = connection.pool.db_config.env_name
1342
1507
  end
1343
1508
 
1344
1509
  def ran?(migration)
@@ -1390,10 +1555,10 @@ module ActiveRecord
1390
1555
  def record_version_state_after_migrating(version)
1391
1556
  if down?
1392
1557
  migrated.delete(version)
1393
- @schema_migration.delete_by(version: version.to_s)
1558
+ @schema_migration.delete_version(version.to_s)
1394
1559
  else
1395
1560
  migrated << version
1396
- @schema_migration.create!(version: version.to_s)
1561
+ @schema_migration.create_version(version.to_s)
1397
1562
  end
1398
1563
  end
1399
1564
 
@@ -1408,50 +1573,38 @@ module ActiveRecord
1408
1573
  # Wrap the migration in a transaction only if supported by the adapter.
1409
1574
  def ddl_transaction(migration, &block)
1410
1575
  if use_transaction?(migration)
1411
- Base.transaction(&block)
1576
+ connection.transaction(&block)
1412
1577
  else
1413
1578
  yield
1414
1579
  end
1415
1580
  end
1416
1581
 
1417
1582
  def use_transaction?(migration)
1418
- !migration.disable_ddl_transaction && Base.connection.supports_ddl_transactions?
1583
+ !migration.disable_ddl_transaction && connection.supports_ddl_transactions?
1419
1584
  end
1420
1585
 
1421
1586
  def use_advisory_lock?
1422
- Base.connection.advisory_locks_enabled?
1587
+ connection.advisory_locks_enabled?
1423
1588
  end
1424
1589
 
1425
1590
  def with_advisory_lock
1426
1591
  lock_id = generate_migrator_advisory_lock_id
1427
1592
 
1428
- with_advisory_lock_connection do |connection|
1429
- got_lock = connection.get_advisory_lock(lock_id)
1430
- raise ConcurrentMigrationError unless got_lock
1431
- load_migrated # reload schema_migrations to be sure it wasn't changed by another process before we got the lock
1432
- yield
1433
- ensure
1434
- if got_lock && !connection.release_advisory_lock(lock_id)
1435
- raise ConcurrentMigrationError.new(
1436
- ConcurrentMigrationError::RELEASE_LOCK_FAILED_MESSAGE
1437
- )
1438
- end
1439
- end
1440
- end
1441
-
1442
- def with_advisory_lock_connection(&block)
1443
- pool = ActiveRecord::ConnectionAdapters::ConnectionHandler.new.establish_connection(
1444
- ActiveRecord::Base.connection_db_config
1445
- )
1446
-
1447
- 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
1448
1597
  ensure
1449
- 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
1450
1603
  end
1451
1604
 
1452
1605
  MIGRATOR_SALT = 2053462845
1453
1606
  def generate_migrator_advisory_lock_id
1454
- db_name_hash = Zlib.crc32(Base.connection.current_database)
1607
+ db_name_hash = Zlib.crc32(connection.current_database)
1455
1608
  MIGRATOR_SALT * db_name_hash
1456
1609
  end
1457
1610
  end