activerecord 7.0.4 → 7.1.5.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 (246) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1971 -1243
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +18 -18
  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 +20 -4
  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 +20 -14
  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 -3
  20. data/lib/active_record/associations/join_dependency/join_association.rb +3 -2
  21. data/lib/active_record/associations/join_dependency.rb +10 -10
  22. data/lib/active_record/associations/preloader/association.rb +31 -7
  23. data/lib/active_record/associations/preloader/through_association.rb +1 -1
  24. data/lib/active_record/associations/preloader.rb +13 -10
  25. data/lib/active_record/associations/singular_association.rb +1 -1
  26. data/lib/active_record/associations/through_association.rb +22 -11
  27. data/lib/active_record/associations.rb +333 -222
  28. data/lib/active_record/attribute_assignment.rb +0 -2
  29. data/lib/active_record/attribute_methods/before_type_cast.rb +17 -0
  30. data/lib/active_record/attribute_methods/dirty.rb +53 -35
  31. data/lib/active_record/attribute_methods/primary_key.rb +76 -24
  32. data/lib/active_record/attribute_methods/query.rb +28 -16
  33. data/lib/active_record/attribute_methods/read.rb +21 -8
  34. data/lib/active_record/attribute_methods/serialization.rb +150 -31
  35. data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -4
  36. data/lib/active_record/attribute_methods/write.rb +6 -6
  37. data/lib/active_record/attribute_methods.rb +148 -26
  38. data/lib/active_record/attributes.rb +3 -3
  39. data/lib/active_record/autosave_association.rb +59 -10
  40. data/lib/active_record/base.rb +7 -2
  41. data/lib/active_record/callbacks.rb +16 -32
  42. data/lib/active_record/coders/column_serializer.rb +61 -0
  43. data/lib/active_record/coders/json.rb +1 -1
  44. data/lib/active_record/coders/yaml_column.rb +70 -42
  45. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +163 -88
  46. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +2 -0
  47. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +3 -1
  48. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +80 -50
  49. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
  50. data/lib/active_record/connection_adapters/abstract/database_statements.rb +129 -31
  51. data/lib/active_record/connection_adapters/abstract/query_cache.rb +62 -23
  52. data/lib/active_record/connection_adapters/abstract/quoting.rb +51 -7
  53. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  54. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +18 -4
  55. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +155 -25
  56. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +297 -127
  57. data/lib/active_record/connection_adapters/abstract/transaction.rb +287 -58
  58. data/lib/active_record/connection_adapters/abstract_adapter.rb +509 -103
  59. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +254 -125
  60. data/lib/active_record/connection_adapters/column.rb +9 -0
  61. data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
  62. data/lib/active_record/connection_adapters/mysql/database_statements.rb +23 -144
  63. data/lib/active_record/connection_adapters/mysql/quoting.rb +29 -14
  64. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
  65. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
  66. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
  67. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +19 -13
  68. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +151 -0
  69. data/lib/active_record/connection_adapters/mysql2_adapter.rb +106 -55
  70. data/lib/active_record/connection_adapters/pool_config.rb +14 -5
  71. data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
  72. data/lib/active_record/connection_adapters/postgresql/column.rb +16 -3
  73. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +75 -45
  74. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  75. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
  76. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
  77. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +11 -2
  78. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +2 -2
  79. data/lib/active_record/connection_adapters/postgresql/quoting.rb +41 -8
  80. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +3 -9
  81. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -6
  82. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +131 -2
  83. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +53 -0
  84. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +365 -61
  85. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
  86. data/lib/active_record/connection_adapters/postgresql_adapter.rb +354 -193
  87. data/lib/active_record/connection_adapters/schema_cache.rb +287 -59
  88. data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
  89. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +52 -39
  90. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +9 -5
  91. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +7 -0
  92. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +28 -9
  93. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +213 -85
  94. data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
  95. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
  96. data/lib/active_record/connection_adapters/trilogy_adapter.rb +258 -0
  97. data/lib/active_record/connection_adapters.rb +3 -1
  98. data/lib/active_record/connection_handling.rb +72 -95
  99. data/lib/active_record/core.rb +181 -154
  100. data/lib/active_record/counter_cache.rb +52 -27
  101. data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -1
  102. data/lib/active_record/database_configurations/database_config.rb +9 -3
  103. data/lib/active_record/database_configurations/hash_config.rb +28 -14
  104. data/lib/active_record/database_configurations/url_config.rb +17 -11
  105. data/lib/active_record/database_configurations.rb +86 -33
  106. data/lib/active_record/delegated_type.rb +15 -10
  107. data/lib/active_record/deprecator.rb +7 -0
  108. data/lib/active_record/destroy_association_async_job.rb +3 -1
  109. data/lib/active_record/disable_joins_association_relation.rb +1 -1
  110. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  111. data/lib/active_record/encryption/cipher/aes256_gcm.rb +4 -1
  112. data/lib/active_record/encryption/config.rb +25 -1
  113. data/lib/active_record/encryption/configurable.rb +12 -19
  114. data/lib/active_record/encryption/context.rb +10 -3
  115. data/lib/active_record/encryption/contexts.rb +5 -1
  116. data/lib/active_record/encryption/derived_secret_key_provider.rb +8 -2
  117. data/lib/active_record/encryption/encryptable_record.rb +42 -18
  118. data/lib/active_record/encryption/encrypted_attribute_type.rb +23 -8
  119. data/lib/active_record/encryption/extended_deterministic_queries.rb +66 -69
  120. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +3 -3
  121. data/lib/active_record/encryption/key_generator.rb +12 -1
  122. data/lib/active_record/encryption/message_serializer.rb +2 -0
  123. data/lib/active_record/encryption/properties.rb +3 -3
  124. data/lib/active_record/encryption/scheme.rb +22 -21
  125. data/lib/active_record/encryption.rb +3 -0
  126. data/lib/active_record/enum.rb +112 -28
  127. data/lib/active_record/errors.rb +112 -18
  128. data/lib/active_record/explain.rb +23 -3
  129. data/lib/active_record/explain_subscriber.rb +1 -1
  130. data/lib/active_record/fixture_set/model_metadata.rb +14 -4
  131. data/lib/active_record/fixture_set/render_context.rb +2 -0
  132. data/lib/active_record/fixture_set/table_row.rb +29 -8
  133. data/lib/active_record/fixtures.rb +135 -71
  134. data/lib/active_record/future_result.rb +40 -5
  135. data/lib/active_record/gem_version.rb +4 -4
  136. data/lib/active_record/inheritance.rb +30 -16
  137. data/lib/active_record/insert_all.rb +57 -10
  138. data/lib/active_record/integration.rb +8 -8
  139. data/lib/active_record/internal_metadata.rb +120 -30
  140. data/lib/active_record/locking/optimistic.rb +33 -19
  141. data/lib/active_record/locking/pessimistic.rb +5 -2
  142. data/lib/active_record/log_subscriber.rb +29 -12
  143. data/lib/active_record/marshalling.rb +59 -0
  144. data/lib/active_record/message_pack.rb +124 -0
  145. data/lib/active_record/middleware/database_selector/resolver.rb +4 -0
  146. data/lib/active_record/middleware/database_selector.rb +9 -11
  147. data/lib/active_record/middleware/shard_selector.rb +3 -1
  148. data/lib/active_record/migration/command_recorder.rb +105 -7
  149. data/lib/active_record/migration/compatibility.rb +163 -58
  150. data/lib/active_record/migration/default_strategy.rb +23 -0
  151. data/lib/active_record/migration/execution_strategy.rb +19 -0
  152. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  153. data/lib/active_record/migration.rb +271 -114
  154. data/lib/active_record/model_schema.rb +69 -44
  155. data/lib/active_record/nested_attributes.rb +37 -8
  156. data/lib/active_record/normalization.rb +167 -0
  157. data/lib/active_record/persistence.rb +195 -42
  158. data/lib/active_record/promise.rb +84 -0
  159. data/lib/active_record/query_cache.rb +4 -22
  160. data/lib/active_record/query_logs.rb +87 -51
  161. data/lib/active_record/query_logs_formatter.rb +41 -0
  162. data/lib/active_record/querying.rb +15 -2
  163. data/lib/active_record/railtie.rb +107 -45
  164. data/lib/active_record/railties/controller_runtime.rb +14 -9
  165. data/lib/active_record/railties/databases.rake +144 -150
  166. data/lib/active_record/railties/job_runtime.rb +23 -0
  167. data/lib/active_record/readonly_attributes.rb +32 -5
  168. data/lib/active_record/reflection.rb +189 -45
  169. data/lib/active_record/relation/batches/batch_enumerator.rb +5 -3
  170. data/lib/active_record/relation/batches.rb +190 -61
  171. data/lib/active_record/relation/calculations.rb +232 -81
  172. data/lib/active_record/relation/delegation.rb +23 -9
  173. data/lib/active_record/relation/finder_methods.rb +77 -16
  174. data/lib/active_record/relation/merger.rb +2 -0
  175. data/lib/active_record/relation/predicate_builder/association_query_value.rb +31 -3
  176. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -7
  177. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  178. data/lib/active_record/relation/predicate_builder.rb +26 -14
  179. data/lib/active_record/relation/query_attribute.rb +25 -1
  180. data/lib/active_record/relation/query_methods.rb +408 -76
  181. data/lib/active_record/relation/spawn_methods.rb +18 -1
  182. data/lib/active_record/relation.rb +103 -37
  183. data/lib/active_record/result.rb +25 -9
  184. data/lib/active_record/runtime_registry.rb +24 -1
  185. data/lib/active_record/sanitization.rb +51 -11
  186. data/lib/active_record/schema.rb +2 -3
  187. data/lib/active_record/schema_dumper.rb +50 -7
  188. data/lib/active_record/schema_migration.rb +68 -33
  189. data/lib/active_record/scoping/default.rb +15 -5
  190. data/lib/active_record/scoping/named.rb +2 -2
  191. data/lib/active_record/scoping.rb +2 -1
  192. data/lib/active_record/secure_password.rb +60 -0
  193. data/lib/active_record/secure_token.rb +21 -3
  194. data/lib/active_record/signed_id.rb +7 -5
  195. data/lib/active_record/store.rb +9 -9
  196. data/lib/active_record/suppressor.rb +3 -1
  197. data/lib/active_record/table_metadata.rb +16 -3
  198. data/lib/active_record/tasks/database_tasks.rb +152 -108
  199. data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
  200. data/lib/active_record/tasks/postgresql_database_tasks.rb +16 -13
  201. data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
  202. data/lib/active_record/test_fixtures.rb +114 -96
  203. data/lib/active_record/timestamp.rb +30 -16
  204. data/lib/active_record/token_for.rb +113 -0
  205. data/lib/active_record/touch_later.rb +11 -6
  206. data/lib/active_record/transactions.rb +39 -13
  207. data/lib/active_record/type/adapter_specific_registry.rb +1 -8
  208. data/lib/active_record/type/internal/timezone.rb +7 -2
  209. data/lib/active_record/type/serialized.rb +8 -4
  210. data/lib/active_record/type/time.rb +4 -0
  211. data/lib/active_record/validations/absence.rb +1 -1
  212. data/lib/active_record/validations/numericality.rb +5 -4
  213. data/lib/active_record/validations/presence.rb +5 -28
  214. data/lib/active_record/validations/uniqueness.rb +47 -2
  215. data/lib/active_record/validations.rb +8 -4
  216. data/lib/active_record/version.rb +1 -1
  217. data/lib/active_record.rb +130 -17
  218. data/lib/arel/errors.rb +10 -0
  219. data/lib/arel/factory_methods.rb +4 -0
  220. data/lib/arel/filter_predications.rb +1 -1
  221. data/lib/arel/nodes/and.rb +4 -0
  222. data/lib/arel/nodes/binary.rb +6 -1
  223. data/lib/arel/nodes/bound_sql_literal.rb +61 -0
  224. data/lib/arel/nodes/cte.rb +36 -0
  225. data/lib/arel/nodes/filter.rb +1 -1
  226. data/lib/arel/nodes/fragments.rb +35 -0
  227. data/lib/arel/nodes/homogeneous_in.rb +1 -9
  228. data/lib/arel/nodes/leading_join.rb +8 -0
  229. data/lib/arel/nodes/node.rb +111 -2
  230. data/lib/arel/nodes/sql_literal.rb +6 -0
  231. data/lib/arel/nodes/table_alias.rb +4 -0
  232. data/lib/arel/nodes.rb +4 -0
  233. data/lib/arel/predications.rb +2 -0
  234. data/lib/arel/table.rb +9 -5
  235. data/lib/arel/tree_manager.rb +5 -1
  236. data/lib/arel/visitors/mysql.rb +8 -1
  237. data/lib/arel/visitors/to_sql.rb +83 -18
  238. data/lib/arel/visitors/visitor.rb +2 -2
  239. data/lib/arel.rb +16 -2
  240. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  241. data/lib/rails/generators/active_record/migration.rb +3 -1
  242. data/lib/rails/generators/active_record/model/USAGE +113 -0
  243. data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
  244. metadata +51 -15
  245. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
  246. data/lib/active_record/null_relation.rb +0 -63
@@ -7,6 +7,7 @@ require "active_support/core_ext/array/access"
7
7
  require "active_support/core_ext/enumerable"
8
8
  require "active_support/core_ext/module/attribute_accessors"
9
9
  require "active_support/actionable_error"
10
+ require "active_record/migration/pending_migration_connection"
10
11
 
11
12
  module ActiveRecord
12
13
  class MigrationError < ActiveRecordError # :nodoc:
@@ -20,7 +21,7 @@ module ActiveRecord
20
21
  # For example the following migration is not reversible.
21
22
  # Rolling back this migration will raise an ActiveRecord::IrreversibleMigration error.
22
23
  #
23
- # class IrreversibleMigrationExample < ActiveRecord::Migration[7.0]
24
+ # class IrreversibleMigrationExample < ActiveRecord::Migration[7.1]
24
25
  # def change
25
26
  # create_table :distributors do |t|
26
27
  # t.string :zipcode
@@ -38,7 +39,7 @@ module ActiveRecord
38
39
  #
39
40
  # 1. Define <tt>#up</tt> and <tt>#down</tt> methods instead of <tt>#change</tt>:
40
41
  #
41
- # class ReversibleMigrationExample < ActiveRecord::Migration[7.0]
42
+ # class ReversibleMigrationExample < ActiveRecord::Migration[7.1]
42
43
  # def up
43
44
  # create_table :distributors do |t|
44
45
  # t.string :zipcode
@@ -63,7 +64,7 @@ module ActiveRecord
63
64
  #
64
65
  # 2. Use the #reversible method in <tt>#change</tt> method:
65
66
  #
66
- # class ReversibleMigrationExample < ActiveRecord::Migration[7.0]
67
+ # class ReversibleMigrationExample < ActiveRecord::Migration[7.1]
67
68
  # def change
68
69
  # create_table :distributors do |t|
69
70
  # t.string :zipcode
@@ -137,32 +138,38 @@ module ActiveRecord
137
138
  ActiveRecord::Tasks::DatabaseTasks.migrate
138
139
 
139
140
  if ActiveRecord.dump_schema_after_migration
140
- ActiveRecord::Tasks::DatabaseTasks.dump_schema(
141
- ActiveRecord::Base.connection_db_config
142
- )
141
+ connection = ActiveRecord::Tasks::DatabaseTasks.migration_connection
142
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema(connection.pool.db_config)
143
143
  end
144
144
  end
145
145
 
146
- def initialize(message = nil)
147
- super(message || detailed_migration_message)
146
+ def initialize(message = nil, pending_migrations: nil)
147
+ if pending_migrations.nil?
148
+ connection = ActiveRecord::Tasks::DatabaseTasks.migration_connection
149
+ pending_migrations = connection.migration_context.open.pending_migrations
150
+ end
151
+
152
+ super(message || detailed_migration_message(pending_migrations))
148
153
  end
149
154
 
150
155
  private
151
- def detailed_migration_message
156
+ def detailed_migration_message(pending_migrations)
152
157
  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)
158
+ message += " RAILS_ENV=#{::Rails.env}" if defined?(Rails.env) && !Rails.env.local?
154
159
  message += "\n\n"
155
160
 
156
- pending_migrations = ActiveRecord::Base.connection.migration_context.open.pending_migrations
157
-
158
161
  message += "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}\n\n"
159
162
 
160
163
  pending_migrations.each do |pending_migration|
161
- message += "#{pending_migration.basename}\n"
164
+ message += "#{pending_migration.filename}\n"
162
165
  end
163
166
 
164
167
  message
165
168
  end
169
+
170
+ def connection
171
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection
172
+ end
166
173
  end
167
174
 
168
175
  class ConcurrentMigrationError < MigrationError # :nodoc:
@@ -228,7 +235,7 @@ module ActiveRecord
228
235
  #
229
236
  # Example of a simple migration:
230
237
  #
231
- # class AddSsl < ActiveRecord::Migration[7.0]
238
+ # class AddSsl < ActiveRecord::Migration[7.1]
232
239
  # def up
233
240
  # add_column :accounts, :ssl_enabled, :boolean, default: true
234
241
  # end
@@ -248,7 +255,7 @@ module ActiveRecord
248
255
  #
249
256
  # Example of a more complex migration that also needs to initialize data:
250
257
  #
251
- # class AddSystemSettings < ActiveRecord::Migration[7.0]
258
+ # class AddSystemSettings < ActiveRecord::Migration[7.1]
252
259
  # def up
253
260
  # create_table :system_settings do |t|
254
261
  # t.string :name
@@ -356,15 +363,16 @@ module ActiveRecord
356
363
  # == Irreversible transformations
357
364
  #
358
365
  # Some transformations are destructive in a manner that cannot be reversed.
359
- # Migrations of that kind should raise an <tt>ActiveRecord::IrreversibleMigration</tt>
366
+ # Migrations of that kind should raise an ActiveRecord::IrreversibleMigration
360
367
  # exception in their +down+ method.
361
368
  #
362
- # == Running migrations from within Rails
369
+ # == Running migrations from within \Rails
363
370
  #
364
- # The Rails package has several tools to help create and apply migrations.
371
+ # The \Rails package has several tools to help create and apply migrations.
365
372
  #
366
373
  # To generate a new migration, you can use
367
- # bin/rails generate migration MyNewMigration
374
+ #
375
+ # $ bin/rails generate migration MyNewMigration
368
376
  #
369
377
  # where MyNewMigration is the name of your migration. The generator will
370
378
  # create an empty migration file <tt>timestamp_my_new_migration.rb</tt>
@@ -373,10 +381,10 @@ module ActiveRecord
373
381
  #
374
382
  # There is a special syntactic shortcut to generate migrations that add fields to a table.
375
383
  #
376
- # bin/rails generate migration add_fieldname_to_tablename fieldname:string
384
+ # $ bin/rails generate migration add_fieldname_to_tablename fieldname:string
377
385
  #
378
386
  # 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]
387
+ # class AddFieldnameToTablename < ActiveRecord::Migration[7.1]
380
388
  # def change
381
389
  # add_column :tablenames, :fieldname, :string
382
390
  # end
@@ -395,14 +403,14 @@ module ActiveRecord
395
403
  # wish to rollback last few migrations. <tt>bin/rails db:rollback STEP=2</tt> will rollback
396
404
  # the latest two migrations.
397
405
  #
398
- # If any of the migrations throw an <tt>ActiveRecord::IrreversibleMigration</tt> exception,
406
+ # If any of the migrations throw an ActiveRecord::IrreversibleMigration exception,
399
407
  # that step will fail and you'll have some manual work to do.
400
408
  #
401
409
  # == More examples
402
410
  #
403
411
  # Not all migrations change the schema. Some just fix the data:
404
412
  #
405
- # class RemoveEmptyTags < ActiveRecord::Migration[7.0]
413
+ # class RemoveEmptyTags < ActiveRecord::Migration[7.1]
406
414
  # def up
407
415
  # Tag.all.each { |tag| tag.destroy if tag.pages.empty? }
408
416
  # end
@@ -415,7 +423,7 @@ module ActiveRecord
415
423
  #
416
424
  # Others remove columns when they migrate up instead of down:
417
425
  #
418
- # class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[7.0]
426
+ # class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[7.1]
419
427
  # def up
420
428
  # remove_column :items, :incomplete_items_count
421
429
  # remove_column :items, :completed_items_count
@@ -429,7 +437,7 @@ module ActiveRecord
429
437
  #
430
438
  # And sometimes you need to do something in SQL not abstracted directly by migrations:
431
439
  #
432
- # class MakeJoinUnique < ActiveRecord::Migration[7.0]
440
+ # class MakeJoinUnique < ActiveRecord::Migration[7.1]
433
441
  # def up
434
442
  # execute "ALTER TABLE `pages_linked_pages` ADD UNIQUE `page_id_linked_page_id` (`page_id`,`linked_page_id`)"
435
443
  # end
@@ -446,7 +454,7 @@ module ActiveRecord
446
454
  # <tt>Base#reset_column_information</tt> in order to ensure that the model has the
447
455
  # latest column data from after the new column was added. Example:
448
456
  #
449
- # class AddPeopleSalary < ActiveRecord::Migration[7.0]
457
+ # class AddPeopleSalary < ActiveRecord::Migration[7.1]
450
458
  # def up
451
459
  # add_column :people, :salary, :integer
452
460
  # Person.reset_column_information
@@ -482,7 +490,7 @@ module ActiveRecord
482
490
  #
483
491
  # == Timestamped Migrations
484
492
  #
485
- # By default, Rails generates migrations that look like:
493
+ # By default, \Rails generates migrations that look like:
486
494
  #
487
495
  # 20080717013526_your_migration_name.rb
488
496
  #
@@ -504,7 +512,7 @@ module ActiveRecord
504
512
  # To define a reversible migration, define the +change+ method in your
505
513
  # migration like this:
506
514
  #
507
- # class TenderloveMigration < ActiveRecord::Migration[7.0]
515
+ # class TenderloveMigration < ActiveRecord::Migration[7.1]
508
516
  # def change
509
517
  # create_table(:horses) do |t|
510
518
  # t.column :content, :text
@@ -521,11 +529,11 @@ module ActiveRecord
521
529
  # as before.
522
530
  #
523
531
  # If a command cannot be reversed, an
524
- # <tt>ActiveRecord::IrreversibleMigration</tt> exception will be raised when
532
+ # ActiveRecord::IrreversibleMigration exception will be raised when
525
533
  # the migration is moving down.
526
534
  #
527
535
  # For a list of commands that are reversible, please see
528
- # <tt>ActiveRecord::Migration::CommandRecorder</tt>.
536
+ # +ActiveRecord::Migration::CommandRecorder+.
529
537
  #
530
538
  # == Transactional Migrations
531
539
  #
@@ -534,7 +542,7 @@ module ActiveRecord
534
542
  # can't execute inside a transaction though, and for these situations
535
543
  # you can turn the automatic transactions off.
536
544
  #
537
- # class ChangeEnum < ActiveRecord::Migration[7.0]
545
+ # class ChangeEnum < ActiveRecord::Migration[7.1]
538
546
  # disable_ddl_transaction!
539
547
  #
540
548
  # def up
@@ -548,9 +556,46 @@ module ActiveRecord
548
556
  autoload :CommandRecorder, "active_record/migration/command_recorder"
549
557
  autoload :Compatibility, "active_record/migration/compatibility"
550
558
  autoload :JoinTable, "active_record/migration/join_table"
559
+ autoload :ExecutionStrategy, "active_record/migration/execution_strategy"
560
+ autoload :DefaultStrategy, "active_record/migration/default_strategy"
551
561
 
552
562
  # This must be defined before the inherited hook, below
553
563
  class Current < Migration # :nodoc:
564
+ def create_table(table_name, **options)
565
+ if block_given?
566
+ super { |t| yield compatible_table_definition(t) }
567
+ else
568
+ super
569
+ end
570
+ end
571
+
572
+ def change_table(table_name, **options)
573
+ if block_given?
574
+ super { |t| yield compatible_table_definition(t) }
575
+ else
576
+ super
577
+ end
578
+ end
579
+
580
+ def create_join_table(table_1, table_2, **options)
581
+ if block_given?
582
+ super { |t| yield compatible_table_definition(t) }
583
+ else
584
+ super
585
+ end
586
+ end
587
+
588
+ def drop_table(table_name, **options)
589
+ if block_given?
590
+ super { |t| yield compatible_table_definition(t) }
591
+ else
592
+ super
593
+ end
594
+ end
595
+
596
+ def compatible_table_definition(t)
597
+ t
598
+ end
554
599
  end
555
600
 
556
601
  def self.inherited(subclass) # :nodoc:
@@ -575,6 +620,13 @@ module ActiveRecord
575
620
 
576
621
  MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/ # :nodoc:
577
622
 
623
+ def self.valid_version_format?(version_string) # :nodoc:
624
+ [
625
+ MigrationFilenameRegexp,
626
+ /\A\d(_?\d)*\z/ # integer with optional underscores
627
+ ].any? { |pattern| pattern.match?(version_string) }
628
+ end
629
+
578
630
  # This class is used to verify that all migrations have been run before
579
631
  # loading a web page if <tt>config.active_record.migration_error</tt> is set to +:page_load+.
580
632
  class CheckPending
@@ -589,7 +641,7 @@ module ActiveRecord
589
641
  @mutex.synchronize do
590
642
  @watcher ||= build_watcher do
591
643
  @needs_check = true
592
- ActiveRecord::Migration.check_pending!(connection)
644
+ ActiveRecord::Migration.check_pending_migrations
593
645
  @needs_check = false
594
646
  end
595
647
 
@@ -605,12 +657,14 @@ module ActiveRecord
605
657
 
606
658
  private
607
659
  def build_watcher(&block)
608
- paths = Array(connection.migration_context.migrations_paths)
660
+ current_environment = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
661
+ all_configs = ActiveRecord::Base.configurations.configs_for(env_name: current_environment)
662
+ paths = all_configs.flat_map { |config| config.migrations_paths || Migrator.migrations_paths }.uniq
609
663
  @file_watcher.new([], paths.index_with(["rb"]), &block)
610
664
  end
611
665
 
612
666
  def connection
613
- ActiveRecord::Base.connection
667
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection
614
668
  end
615
669
  end
616
670
 
@@ -622,32 +676,53 @@ module ActiveRecord
622
676
  delegate || superclass.nearest_delegate
623
677
  end
624
678
 
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?
679
+ # Raises ActiveRecord::PendingMigrationError error if any migrations are pending.
680
+ #
681
+ # This is deprecated in favor of +check_all_pending!+
682
+ def check_pending!(connection = ActiveRecord::Tasks::DatabaseTasks.migration_connection)
683
+ ActiveRecord.deprecator.warn(<<-MSG.squish)
684
+ The `check_pending!` method is deprecated in favor of `check_all_pending!`. The
685
+ new implementation will loop through all available database configurations and find
686
+ pending migrations. The prior implementation did not permit this.
687
+ MSG
688
+
689
+ pending_migrations = connection.migration_context.open.pending_migrations
690
+
691
+ if pending_migrations.any?
692
+ raise ActiveRecord::PendingMigrationError.new(pending_migrations: pending_migrations)
693
+ end
628
694
  end
629
695
 
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)
696
+ # Raises ActiveRecord::PendingMigrationError error if any migrations are pending
697
+ # for all database configurations in an environment.
698
+ def check_all_pending!
699
+ pending_migrations = []
633
700
 
634
- needs_update = !all_configs.all? do |db_config|
635
- Tasks::DatabaseTasks.schema_up_to_date?(db_config, ActiveRecord.schema_format)
701
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: env) do |connection|
702
+ if pending = connection.migration_context.open.pending_migrations
703
+ pending_migrations << pending
704
+ end
636
705
  end
637
706
 
638
- if needs_update
707
+ migrations = pending_migrations.flatten
708
+
709
+ if migrations.any?
710
+ raise ActiveRecord::PendingMigrationError.new(pending_migrations: migrations)
711
+ end
712
+ end
713
+
714
+ def load_schema_if_pending!
715
+ if any_schema_needs_update?
639
716
  # Roundtrip to Rake to allow plugins to hook into database initialization.
640
717
  root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
718
+
641
719
  FileUtils.cd(root) do
642
- Base.clear_all_connections!
720
+ Base.connection_handler.clear_all_connections!(:all)
643
721
  system("bin/rails db:test:prepare")
644
722
  end
645
723
  end
646
724
 
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!
725
+ check_pending_migrations
651
726
  end
652
727
 
653
728
  def maintain_test_schema! # :nodoc:
@@ -672,6 +747,43 @@ module ActiveRecord
672
747
  def disable_ddl_transaction!
673
748
  @disable_ddl_transaction = true
674
749
  end
750
+
751
+ def check_pending_migrations # :nodoc:
752
+ migrations = pending_migrations
753
+
754
+ if migrations.any?
755
+ raise ActiveRecord::PendingMigrationError.new(pending_migrations: migrations)
756
+ end
757
+ end
758
+
759
+ private
760
+ def any_schema_needs_update?
761
+ !db_configs_in_current_env.all? do |db_config|
762
+ Tasks::DatabaseTasks.schema_up_to_date?(db_config, ActiveRecord.schema_format)
763
+ end
764
+ end
765
+
766
+ def db_configs_in_current_env
767
+ ActiveRecord::Base.configurations.configs_for(env_name: env)
768
+ end
769
+
770
+ def pending_migrations
771
+ pending_migrations = []
772
+
773
+ ActiveRecord::Base.configurations.configs_for(env_name: env).each do |db_config|
774
+ ActiveRecord::PendingMigrationConnection.establish_temporary_connection(db_config) do |conn|
775
+ if pending = conn.migration_context.open.pending_migrations
776
+ pending_migrations << pending
777
+ end
778
+ end
779
+ end
780
+
781
+ pending_migrations.flatten
782
+ end
783
+
784
+ def env
785
+ ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
786
+ end
675
787
  end
676
788
 
677
789
  def disable_ddl_transaction # :nodoc:
@@ -687,6 +799,10 @@ module ActiveRecord
687
799
  @connection = nil
688
800
  end
689
801
 
802
+ def execution_strategy
803
+ @execution_strategy ||= ActiveRecord.migration_strategy.new(self)
804
+ end
805
+
690
806
  self.verbose = true
691
807
  # instantiate the delegate object after initialize is defined
692
808
  self.delegate = new
@@ -698,7 +814,7 @@ module ActiveRecord
698
814
  # and create the table 'apples' on the way up, and the reverse
699
815
  # on the way down.
700
816
  #
701
- # class FixTLMigration < ActiveRecord::Migration[7.0]
817
+ # class FixTLMigration < ActiveRecord::Migration[7.1]
702
818
  # def change
703
819
  # revert do
704
820
  # create_table(:horses) do |t|
@@ -717,7 +833,7 @@ module ActiveRecord
717
833
  #
718
834
  # require_relative "20121212123456_tenderlove_migration"
719
835
  #
720
- # class FixupTLMigration < ActiveRecord::Migration[7.0]
836
+ # class FixupTLMigration < ActiveRecord::Migration[7.1]
721
837
  # def change
722
838
  # revert TenderloveMigration
723
839
  #
@@ -768,7 +884,7 @@ module ActiveRecord
768
884
  # when the three columns 'first_name', 'last_name' and 'full_name' exist,
769
885
  # even when migrating down:
770
886
  #
771
- # class SplitNameMigration < ActiveRecord::Migration[7.0]
887
+ # class SplitNameMigration < ActiveRecord::Migration[7.1]
772
888
  # def change
773
889
  # add_column :users, :first_name, :string
774
890
  # add_column :users, :last_name, :string
@@ -796,7 +912,7 @@ module ActiveRecord
796
912
  # In the following example, the new column +published+ will be given
797
913
  # the value +true+ for all existing records.
798
914
  #
799
- # class AddPublishedToPosts < ActiveRecord::Migration[7.0]
915
+ # class AddPublishedToPosts < ActiveRecord::Migration[7.1]
800
916
  # def change
801
917
  # add_column :posts, :published, :boolean, default: false
802
918
  # up_only do
@@ -849,7 +965,7 @@ module ActiveRecord
849
965
  end
850
966
 
851
967
  time = nil
852
- ActiveRecord::Base.connection_pool.with_connection do |conn|
968
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection.pool.with_connection do |conn|
853
969
  time = Benchmark.measure do
854
970
  exec_migration(conn, direction)
855
971
  end
@@ -874,6 +990,7 @@ module ActiveRecord
874
990
  end
875
991
  ensure
876
992
  @connection = nil
993
+ @execution_strategy = nil
877
994
  end
878
995
 
879
996
  def write(text = "")
@@ -912,13 +1029,11 @@ module ActiveRecord
912
1029
  end
913
1030
 
914
1031
  def connection
915
- @connection || ActiveRecord::Base.connection
1032
+ @connection || ActiveRecord::Tasks::DatabaseTasks.migration_connection
916
1033
  end
917
1034
 
918
1035
  def method_missing(method, *arguments, &block)
919
- arg_list = arguments.map(&:inspect) * ", "
920
-
921
- say_with_time "#{method}(#{arg_list})" do
1036
+ say_with_time "#{method}(#{format_arguments(arguments)})" do
922
1037
  unless connection.respond_to? :revert
923
1038
  unless arguments.empty? || [:execute, :enable_extension, :disable_extension].include?(method)
924
1039
  arguments[0] = proper_table_name(arguments.first, table_name_options)
@@ -928,22 +1043,23 @@ module ActiveRecord
928
1043
  end
929
1044
  end
930
1045
  end
931
- return super unless connection.respond_to?(method)
932
- connection.send(method, *arguments, &block)
1046
+ return super unless execution_strategy.respond_to?(method)
1047
+ execution_strategy.send(method, *arguments, &block)
933
1048
  end
934
1049
  end
935
1050
  ruby2_keywords(:method_missing)
936
1051
 
937
1052
  def copy(destination, sources, options = {})
938
1053
  copied = []
939
- schema_migration = options[:schema_migration] || ActiveRecord::SchemaMigration
940
1054
 
941
1055
  FileUtils.mkdir_p(destination) unless File.exist?(destination)
1056
+ schema_migration = SchemaMigration::NullSchemaMigration.new
1057
+ internal_metadata = InternalMetadata::NullInternalMetadata.new
942
1058
 
943
- destination_migrations = ActiveRecord::MigrationContext.new(destination, schema_migration).migrations
1059
+ destination_migrations = ActiveRecord::MigrationContext.new(destination, schema_migration, internal_metadata).migrations
944
1060
  last = destination_migrations.last
945
1061
  sources.each do |scope, path|
946
- source_migrations = ActiveRecord::MigrationContext.new(path, schema_migration).migrations
1062
+ source_migrations = ActiveRecord::MigrationContext.new(path, schema_migration, internal_metadata).migrations
947
1063
 
948
1064
  source_migrations.each do |migration|
949
1065
  source = File.binread(migration.filename)
@@ -1004,7 +1120,7 @@ module ActiveRecord
1004
1120
  if ActiveRecord.timestamped_migrations
1005
1121
  [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % number].max
1006
1122
  else
1007
- SchemaMigration.normalize_migration_number(number)
1123
+ "%.3d" % number.to_i
1008
1124
  end
1009
1125
  end
1010
1126
 
@@ -1026,6 +1142,22 @@ module ActiveRecord
1026
1142
  end
1027
1143
  end
1028
1144
 
1145
+ def format_arguments(arguments)
1146
+ arg_list = arguments[0...-1].map(&:inspect)
1147
+ last_arg = arguments.last
1148
+ if last_arg.is_a?(Hash)
1149
+ last_arg = last_arg.reject { |k, _v| internal_option?(k) }
1150
+ arg_list << last_arg.inspect unless last_arg.empty?
1151
+ else
1152
+ arg_list << last_arg.inspect
1153
+ end
1154
+ arg_list.join(", ")
1155
+ end
1156
+
1157
+ def internal_option?(option_name)
1158
+ option_name.start_with?("_")
1159
+ end
1160
+
1029
1161
  def command_recorder
1030
1162
  CommandRecorder.new(connection)
1031
1163
  end
@@ -1058,19 +1190,44 @@ module ActiveRecord
1058
1190
  end
1059
1191
  end
1060
1192
 
1193
+ # = \Migration \Context
1194
+ #
1061
1195
  # MigrationContext sets the context in which a migration is run.
1062
1196
  #
1063
1197
  # A migration context requires the path to the migrations is set
1064
1198
  # 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.
1199
+ # class can be provided. Multiple database applications will instantiate
1200
+ # a +SchemaMigration+ object per database. From the Rake tasks, \Rails will
1201
+ # handle this for you.
1068
1202
  class MigrationContext
1069
- attr_reader :migrations_paths, :schema_migration
1203
+ attr_reader :migrations_paths, :schema_migration, :internal_metadata
1204
+
1205
+ def initialize(migrations_paths, schema_migration = nil, internal_metadata = nil)
1206
+ if schema_migration == SchemaMigration
1207
+ ActiveRecord.deprecator.warn(<<-MSG.squish)
1208
+ SchemaMigration no longer inherits from ActiveRecord::Base. If you want
1209
+ to use the default connection, remove this argument. If you want to use a
1210
+ specific connection, instantiate MigrationContext with the connection's schema
1211
+ migration, for example `MigrationContext.new(path, Dog.connection.schema_migration)`.
1212
+ MSG
1213
+
1214
+ schema_migration = nil
1215
+ end
1216
+
1217
+ if internal_metadata == InternalMetadata
1218
+ ActiveRecord.deprecator.warn(<<-MSG.squish)
1219
+ SchemaMigration no longer inherits from ActiveRecord::Base. If you want
1220
+ to use the default connection, remove this argument. If you want to use a
1221
+ specific connection, instantiate MigrationContext with the connection's internal
1222
+ metadata, for example `MigrationContext.new(path, nil, Dog.connection.internal_metadata)`.
1223
+ MSG
1224
+
1225
+ internal_metadata = nil
1226
+ end
1070
1227
 
1071
- def initialize(migrations_paths, schema_migration = SchemaMigration)
1072
1228
  @migrations_paths = migrations_paths
1073
- @schema_migration = schema_migration
1229
+ @schema_migration = schema_migration || SchemaMigration.new(connection)
1230
+ @internal_metadata = internal_metadata || InternalMetadata.new(connection)
1074
1231
  end
1075
1232
 
1076
1233
  # Runs the migrations in the +migrations_path+.
@@ -1114,7 +1271,7 @@ module ActiveRecord
1114
1271
  migrations
1115
1272
  end
1116
1273
 
1117
- Migrator.new(:up, selected_migrations, schema_migration, target_version).migrate
1274
+ Migrator.new(:up, selected_migrations, schema_migration, internal_metadata, target_version).migrate
1118
1275
  end
1119
1276
 
1120
1277
  def down(target_version = nil, &block) # :nodoc:
@@ -1124,20 +1281,20 @@ module ActiveRecord
1124
1281
  migrations
1125
1282
  end
1126
1283
 
1127
- Migrator.new(:down, selected_migrations, schema_migration, target_version).migrate
1284
+ Migrator.new(:down, selected_migrations, schema_migration, internal_metadata, target_version).migrate
1128
1285
  end
1129
1286
 
1130
1287
  def run(direction, target_version) # :nodoc:
1131
- Migrator.new(direction, migrations, schema_migration, target_version).run
1288
+ Migrator.new(direction, migrations, schema_migration, internal_metadata, target_version).run
1132
1289
  end
1133
1290
 
1134
1291
  def open # :nodoc:
1135
- Migrator.new(:up, migrations, schema_migration)
1292
+ Migrator.new(:up, migrations, schema_migration, internal_metadata)
1136
1293
  end
1137
1294
 
1138
1295
  def get_all_versions # :nodoc:
1139
1296
  if schema_migration.table_exists?
1140
- schema_migration.all_versions.map(&:to_i)
1297
+ schema_migration.integer_versions
1141
1298
  else
1142
1299
  []
1143
1300
  end
@@ -1196,16 +1353,20 @@ module ActiveRecord
1196
1353
  end
1197
1354
 
1198
1355
  def last_stored_environment # :nodoc:
1199
- return nil unless ActiveRecord::InternalMetadata.enabled?
1356
+ return nil unless connection.internal_metadata.enabled?
1200
1357
  return nil if current_version == 0
1201
- raise NoEnvironmentInSchemaError unless ActiveRecord::InternalMetadata.table_exists?
1358
+ raise NoEnvironmentInSchemaError unless connection.internal_metadata.table_exists?
1202
1359
 
1203
- environment = ActiveRecord::InternalMetadata[:environment]
1360
+ environment = connection.internal_metadata[:environment]
1204
1361
  raise NoEnvironmentInSchemaError unless environment
1205
1362
  environment
1206
1363
  end
1207
1364
 
1208
1365
  private
1366
+ def connection
1367
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection
1368
+ end
1369
+
1209
1370
  def migration_files
1210
1371
  paths = Array(migrations_paths)
1211
1372
  Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
@@ -1216,7 +1377,7 @@ module ActiveRecord
1216
1377
  end
1217
1378
 
1218
1379
  def move(direction, steps)
1219
- migrator = Migrator.new(direction, migrations, schema_migration)
1380
+ migrator = Migrator.new(direction, migrations, schema_migration, internal_metadata)
1220
1381
 
1221
1382
  if current_version != 0 && !migrator.current_migration
1222
1383
  raise UnknownMigrationVersionError.new(current_version)
@@ -1241,23 +1402,28 @@ module ActiveRecord
1241
1402
 
1242
1403
  # For cases where a table doesn't exist like loading from schema cache
1243
1404
  def current_version
1244
- MigrationContext.new(migrations_paths, SchemaMigration).current_version
1405
+ connection = ActiveRecord::Tasks::DatabaseTasks.migration_connection
1406
+ schema_migration = SchemaMigration.new(connection)
1407
+ internal_metadata = InternalMetadata.new(connection)
1408
+
1409
+ MigrationContext.new(migrations_paths, schema_migration, internal_metadata).current_version
1245
1410
  end
1246
1411
  end
1247
1412
 
1248
1413
  self.migrations_paths = ["db/migrate"]
1249
1414
 
1250
- def initialize(direction, migrations, schema_migration, target_version = nil)
1415
+ def initialize(direction, migrations, schema_migration, internal_metadata, target_version = nil)
1251
1416
  @direction = direction
1252
1417
  @target_version = target_version
1253
1418
  @migrated_versions = nil
1254
1419
  @migrations = migrations
1255
1420
  @schema_migration = schema_migration
1421
+ @internal_metadata = internal_metadata
1256
1422
 
1257
1423
  validate(@migrations)
1258
1424
 
1259
1425
  @schema_migration.create_table
1260
- ActiveRecord::InternalMetadata.create_table
1426
+ @internal_metadata.create_table
1261
1427
  end
1262
1428
 
1263
1429
  def current_version
@@ -1310,18 +1476,21 @@ module ActiveRecord
1310
1476
  end
1311
1477
 
1312
1478
  def load_migrated
1313
- @migrated_versions = Set.new(@schema_migration.all_versions.map(&:to_i))
1479
+ @migrated_versions = Set.new(@schema_migration.integer_versions)
1314
1480
  end
1315
1481
 
1316
1482
  private
1483
+ def connection
1484
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection
1485
+ end
1486
+
1317
1487
  # Used for running a specific migration.
1318
1488
  def run_without_lock
1319
1489
  migration = migrations.detect { |m| m.version == @target_version }
1320
1490
  raise UnknownMigrationVersionError.new(@target_version) if migration.nil?
1321
- result = execute_migration_in_transaction(migration)
1322
1491
 
1323
1492
  record_environment
1324
- result
1493
+ execute_migration_in_transaction(migration)
1325
1494
  end
1326
1495
 
1327
1496
  # Used for running multiple migrations up to or down to a certain value.
@@ -1330,15 +1499,15 @@ module ActiveRecord
1330
1499
  raise UnknownMigrationVersionError.new(@target_version)
1331
1500
  end
1332
1501
 
1333
- result = runnable.each(&method(:execute_migration_in_transaction))
1334
1502
  record_environment
1335
- result
1503
+ runnable.each(&method(:execute_migration_in_transaction))
1336
1504
  end
1337
1505
 
1338
1506
  # Stores the current environment in the database.
1339
1507
  def record_environment
1340
1508
  return if down?
1341
- ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Base.connection.migration_context.current_environment
1509
+
1510
+ @internal_metadata[:environment] = connection.pool.db_config.env_name
1342
1511
  end
1343
1512
 
1344
1513
  def ran?(migration)
@@ -1390,10 +1559,10 @@ module ActiveRecord
1390
1559
  def record_version_state_after_migrating(version)
1391
1560
  if down?
1392
1561
  migrated.delete(version)
1393
- @schema_migration.delete_by(version: version.to_s)
1562
+ @schema_migration.delete_version(version.to_s)
1394
1563
  else
1395
1564
  migrated << version
1396
- @schema_migration.create!(version: version.to_s)
1565
+ @schema_migration.create_version(version.to_s)
1397
1566
  end
1398
1567
  end
1399
1568
 
@@ -1408,50 +1577,38 @@ module ActiveRecord
1408
1577
  # Wrap the migration in a transaction only if supported by the adapter.
1409
1578
  def ddl_transaction(migration, &block)
1410
1579
  if use_transaction?(migration)
1411
- Base.transaction(&block)
1580
+ connection.transaction(&block)
1412
1581
  else
1413
1582
  yield
1414
1583
  end
1415
1584
  end
1416
1585
 
1417
1586
  def use_transaction?(migration)
1418
- !migration.disable_ddl_transaction && Base.connection.supports_ddl_transactions?
1587
+ !migration.disable_ddl_transaction && connection.supports_ddl_transactions?
1419
1588
  end
1420
1589
 
1421
1590
  def use_advisory_lock?
1422
- Base.connection.advisory_locks_enabled?
1591
+ connection.advisory_locks_enabled?
1423
1592
  end
1424
1593
 
1425
1594
  def with_advisory_lock
1426
1595
  lock_id = generate_migrator_advisory_lock_id
1427
1596
 
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)
1597
+ got_lock = connection.get_advisory_lock(lock_id)
1598
+ raise ConcurrentMigrationError unless got_lock
1599
+ load_migrated # reload schema_migrations to be sure it wasn't changed by another process before we got the lock
1600
+ yield
1448
1601
  ensure
1449
- pool&.disconnect!
1602
+ if got_lock && !connection.release_advisory_lock(lock_id)
1603
+ raise ConcurrentMigrationError.new(
1604
+ ConcurrentMigrationError::RELEASE_LOCK_FAILED_MESSAGE
1605
+ )
1606
+ end
1450
1607
  end
1451
1608
 
1452
1609
  MIGRATOR_SALT = 2053462845
1453
1610
  def generate_migrator_advisory_lock_id
1454
- db_name_hash = Zlib.crc32(Base.connection.current_database)
1611
+ db_name_hash = Zlib.crc32(connection.current_database)
1455
1612
  MIGRATOR_SALT * db_name_hash
1456
1613
  end
1457
1614
  end