activerecord 7.0.0 → 7.1.2

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