activerecord 7.0.8 → 7.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (231) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1460 -1477
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +16 -16
  5. data/lib/active_record/aggregations.rb +16 -13
  6. data/lib/active_record/association_relation.rb +1 -1
  7. data/lib/active_record/associations/association.rb +18 -3
  8. data/lib/active_record/associations/association_scope.rb +16 -9
  9. data/lib/active_record/associations/belongs_to_association.rb +14 -6
  10. data/lib/active_record/associations/builder/association.rb +3 -3
  11. data/lib/active_record/associations/builder/belongs_to.rb +21 -8
  12. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
  13. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  14. data/lib/active_record/associations/collection_association.rb +15 -9
  15. data/lib/active_record/associations/collection_proxy.rb +15 -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.rb +10 -8
  21. data/lib/active_record/associations/preloader/association.rb +27 -6
  22. data/lib/active_record/associations/preloader.rb +13 -10
  23. data/lib/active_record/associations/singular_association.rb +1 -1
  24. data/lib/active_record/associations/through_association.rb +22 -11
  25. data/lib/active_record/associations.rb +312 -216
  26. data/lib/active_record/attribute_assignment.rb +0 -2
  27. data/lib/active_record/attribute_methods/before_type_cast.rb +17 -0
  28. data/lib/active_record/attribute_methods/dirty.rb +52 -34
  29. data/lib/active_record/attribute_methods/primary_key.rb +76 -24
  30. data/lib/active_record/attribute_methods/query.rb +28 -16
  31. data/lib/active_record/attribute_methods/read.rb +18 -5
  32. data/lib/active_record/attribute_methods/serialization.rb +150 -31
  33. data/lib/active_record/attribute_methods/write.rb +3 -3
  34. data/lib/active_record/attribute_methods.rb +105 -21
  35. data/lib/active_record/attributes.rb +3 -3
  36. data/lib/active_record/autosave_association.rb +55 -9
  37. data/lib/active_record/base.rb +7 -2
  38. data/lib/active_record/callbacks.rb +10 -24
  39. data/lib/active_record/coders/column_serializer.rb +61 -0
  40. data/lib/active_record/coders/json.rb +1 -1
  41. data/lib/active_record/coders/yaml_column.rb +70 -42
  42. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +163 -88
  43. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +2 -0
  44. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +3 -1
  45. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +63 -43
  46. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
  47. data/lib/active_record/connection_adapters/abstract/database_statements.rb +129 -31
  48. data/lib/active_record/connection_adapters/abstract/query_cache.rb +60 -22
  49. data/lib/active_record/connection_adapters/abstract/quoting.rb +41 -6
  50. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  51. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +18 -4
  52. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +137 -11
  53. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +289 -124
  54. data/lib/active_record/connection_adapters/abstract/transaction.rb +287 -58
  55. data/lib/active_record/connection_adapters/abstract_adapter.rb +511 -91
  56. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +207 -108
  57. data/lib/active_record/connection_adapters/column.rb +9 -0
  58. data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
  59. data/lib/active_record/connection_adapters/mysql/database_statements.rb +22 -143
  60. data/lib/active_record/connection_adapters/mysql/quoting.rb +16 -12
  61. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
  62. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +6 -0
  63. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
  64. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +18 -13
  65. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +151 -0
  66. data/lib/active_record/connection_adapters/mysql2_adapter.rb +98 -53
  67. data/lib/active_record/connection_adapters/pool_config.rb +14 -5
  68. data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
  69. data/lib/active_record/connection_adapters/postgresql/column.rb +14 -3
  70. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +74 -40
  71. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
  72. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +11 -2
  73. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +1 -1
  74. data/lib/active_record/connection_adapters/postgresql/quoting.rb +10 -6
  75. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +3 -9
  76. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -6
  77. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +131 -2
  78. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +53 -0
  79. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +361 -60
  80. data/lib/active_record/connection_adapters/postgresql_adapter.rb +353 -192
  81. data/lib/active_record/connection_adapters/schema_cache.rb +287 -59
  82. data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
  83. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +52 -39
  84. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +4 -3
  85. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +1 -0
  86. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +26 -7
  87. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +209 -79
  88. data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
  89. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
  90. data/lib/active_record/connection_adapters/trilogy_adapter.rb +254 -0
  91. data/lib/active_record/connection_adapters.rb +3 -1
  92. data/lib/active_record/connection_handling.rb +71 -94
  93. data/lib/active_record/core.rb +140 -151
  94. data/lib/active_record/counter_cache.rb +46 -25
  95. data/lib/active_record/database_configurations/database_config.rb +9 -3
  96. data/lib/active_record/database_configurations/hash_config.rb +22 -12
  97. data/lib/active_record/database_configurations/url_config.rb +17 -11
  98. data/lib/active_record/database_configurations.rb +86 -33
  99. data/lib/active_record/delegated_type.rb +8 -3
  100. data/lib/active_record/deprecator.rb +7 -0
  101. data/lib/active_record/destroy_association_async_job.rb +2 -0
  102. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  103. data/lib/active_record/encryption/cipher/aes256_gcm.rb +4 -1
  104. data/lib/active_record/encryption/config.rb +25 -1
  105. data/lib/active_record/encryption/configurable.rb +12 -19
  106. data/lib/active_record/encryption/context.rb +10 -3
  107. data/lib/active_record/encryption/contexts.rb +5 -1
  108. data/lib/active_record/encryption/derived_secret_key_provider.rb +8 -2
  109. data/lib/active_record/encryption/encryptable_record.rb +36 -18
  110. data/lib/active_record/encryption/encrypted_attribute_type.rb +17 -6
  111. data/lib/active_record/encryption/extended_deterministic_queries.rb +66 -69
  112. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +3 -3
  113. data/lib/active_record/encryption/key_generator.rb +12 -1
  114. data/lib/active_record/encryption/message_serializer.rb +2 -0
  115. data/lib/active_record/encryption/properties.rb +3 -3
  116. data/lib/active_record/encryption/scheme.rb +19 -22
  117. data/lib/active_record/encryption.rb +1 -0
  118. data/lib/active_record/enum.rb +112 -28
  119. data/lib/active_record/errors.rb +108 -15
  120. data/lib/active_record/explain.rb +23 -3
  121. data/lib/active_record/fixture_set/model_metadata.rb +14 -4
  122. data/lib/active_record/fixture_set/render_context.rb +2 -0
  123. data/lib/active_record/fixture_set/table_row.rb +29 -8
  124. data/lib/active_record/fixtures.rb +119 -71
  125. data/lib/active_record/future_result.rb +30 -5
  126. data/lib/active_record/gem_version.rb +3 -3
  127. data/lib/active_record/inheritance.rb +30 -16
  128. data/lib/active_record/insert_all.rb +57 -10
  129. data/lib/active_record/integration.rb +8 -8
  130. data/lib/active_record/internal_metadata.rb +120 -30
  131. data/lib/active_record/locking/pessimistic.rb +5 -2
  132. data/lib/active_record/log_subscriber.rb +29 -12
  133. data/lib/active_record/marshalling.rb +56 -0
  134. data/lib/active_record/message_pack.rb +124 -0
  135. data/lib/active_record/middleware/database_selector/resolver.rb +4 -0
  136. data/lib/active_record/middleware/database_selector.rb +5 -7
  137. data/lib/active_record/middleware/shard_selector.rb +3 -1
  138. data/lib/active_record/migration/command_recorder.rb +104 -5
  139. data/lib/active_record/migration/compatibility.rb +131 -5
  140. data/lib/active_record/migration/default_strategy.rb +23 -0
  141. data/lib/active_record/migration/execution_strategy.rb +19 -0
  142. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  143. data/lib/active_record/migration.rb +216 -109
  144. data/lib/active_record/model_schema.rb +64 -44
  145. data/lib/active_record/nested_attributes.rb +24 -6
  146. data/lib/active_record/normalization.rb +167 -0
  147. data/lib/active_record/persistence.rb +184 -34
  148. data/lib/active_record/promise.rb +84 -0
  149. data/lib/active_record/query_cache.rb +3 -21
  150. data/lib/active_record/query_logs.rb +77 -52
  151. data/lib/active_record/query_logs_formatter.rb +41 -0
  152. data/lib/active_record/querying.rb +15 -2
  153. data/lib/active_record/railtie.rb +109 -47
  154. data/lib/active_record/railties/controller_runtime.rb +10 -5
  155. data/lib/active_record/railties/databases.rake +142 -148
  156. data/lib/active_record/railties/job_runtime.rb +23 -0
  157. data/lib/active_record/readonly_attributes.rb +32 -5
  158. data/lib/active_record/reflection.rb +174 -44
  159. data/lib/active_record/relation/batches/batch_enumerator.rb +5 -3
  160. data/lib/active_record/relation/batches.rb +190 -61
  161. data/lib/active_record/relation/calculations.rb +160 -63
  162. data/lib/active_record/relation/delegation.rb +22 -8
  163. data/lib/active_record/relation/finder_methods.rb +77 -16
  164. data/lib/active_record/relation/merger.rb +2 -0
  165. data/lib/active_record/relation/predicate_builder/association_query_value.rb +11 -2
  166. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -6
  167. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  168. data/lib/active_record/relation/predicate_builder.rb +26 -14
  169. data/lib/active_record/relation/query_attribute.rb +2 -1
  170. data/lib/active_record/relation/query_methods.rb +352 -63
  171. data/lib/active_record/relation/spawn_methods.rb +18 -1
  172. data/lib/active_record/relation.rb +76 -35
  173. data/lib/active_record/result.rb +19 -5
  174. data/lib/active_record/runtime_registry.rb +10 -1
  175. data/lib/active_record/sanitization.rb +51 -11
  176. data/lib/active_record/schema.rb +2 -3
  177. data/lib/active_record/schema_dumper.rb +46 -7
  178. data/lib/active_record/schema_migration.rb +68 -33
  179. data/lib/active_record/scoping/default.rb +15 -5
  180. data/lib/active_record/scoping/named.rb +2 -2
  181. data/lib/active_record/scoping.rb +2 -1
  182. data/lib/active_record/secure_password.rb +60 -0
  183. data/lib/active_record/secure_token.rb +21 -3
  184. data/lib/active_record/signed_id.rb +7 -5
  185. data/lib/active_record/store.rb +8 -8
  186. data/lib/active_record/suppressor.rb +3 -1
  187. data/lib/active_record/table_metadata.rb +10 -1
  188. data/lib/active_record/tasks/database_tasks.rb +127 -105
  189. data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
  190. data/lib/active_record/tasks/postgresql_database_tasks.rb +16 -13
  191. data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
  192. data/lib/active_record/test_fixtures.rb +113 -96
  193. data/lib/active_record/timestamp.rb +27 -15
  194. data/lib/active_record/token_for.rb +113 -0
  195. data/lib/active_record/touch_later.rb +11 -6
  196. data/lib/active_record/transactions.rb +36 -10
  197. data/lib/active_record/type/adapter_specific_registry.rb +1 -8
  198. data/lib/active_record/type/internal/timezone.rb +7 -2
  199. data/lib/active_record/type/time.rb +4 -0
  200. data/lib/active_record/validations/absence.rb +1 -1
  201. data/lib/active_record/validations/numericality.rb +5 -4
  202. data/lib/active_record/validations/presence.rb +5 -28
  203. data/lib/active_record/validations/uniqueness.rb +47 -2
  204. data/lib/active_record/validations.rb +8 -4
  205. data/lib/active_record/version.rb +1 -1
  206. data/lib/active_record.rb +121 -16
  207. data/lib/arel/errors.rb +10 -0
  208. data/lib/arel/factory_methods.rb +4 -0
  209. data/lib/arel/nodes/binary.rb +6 -1
  210. data/lib/arel/nodes/bound_sql_literal.rb +61 -0
  211. data/lib/arel/nodes/cte.rb +36 -0
  212. data/lib/arel/nodes/fragments.rb +35 -0
  213. data/lib/arel/nodes/homogeneous_in.rb +1 -9
  214. data/lib/arel/nodes/leading_join.rb +8 -0
  215. data/lib/arel/nodes/node.rb +111 -2
  216. data/lib/arel/nodes/sql_literal.rb +6 -0
  217. data/lib/arel/nodes/table_alias.rb +4 -0
  218. data/lib/arel/nodes.rb +4 -0
  219. data/lib/arel/predications.rb +2 -0
  220. data/lib/arel/table.rb +9 -5
  221. data/lib/arel/visitors/mysql.rb +8 -1
  222. data/lib/arel/visitors/to_sql.rb +81 -17
  223. data/lib/arel/visitors/visitor.rb +2 -2
  224. data/lib/arel.rb +16 -2
  225. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  226. data/lib/rails/generators/active_record/migration.rb +3 -1
  227. data/lib/rails/generators/active_record/model/USAGE +113 -0
  228. data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
  229. metadata +47 -11
  230. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
  231. 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,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,6 +555,8 @@ 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:
@@ -610,6 +619,13 @@ module ActiveRecord
610
619
 
611
620
  MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/ # :nodoc:
612
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
+
613
629
  # This class is used to verify that all migrations have been run before
614
630
  # loading a web page if <tt>config.active_record.migration_error</tt> is set to +:page_load+.
615
631
  class CheckPending
@@ -624,7 +640,7 @@ module ActiveRecord
624
640
  @mutex.synchronize do
625
641
  @watcher ||= build_watcher do
626
642
  @needs_check = true
627
- ActiveRecord::Migration.check_pending!(connection)
643
+ ActiveRecord::Migration.check_pending_migrations
628
644
  @needs_check = false
629
645
  end
630
646
 
@@ -640,12 +656,14 @@ module ActiveRecord
640
656
 
641
657
  private
642
658
  def build_watcher(&block)
643
- 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
644
662
  @file_watcher.new([], paths.index_with(["rb"]), &block)
645
663
  end
646
664
 
647
665
  def connection
648
- ActiveRecord::Base.connection
666
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection
649
667
  end
650
668
  end
651
669
 
@@ -657,32 +675,53 @@ module ActiveRecord
657
675
  delegate || superclass.nearest_delegate
658
676
  end
659
677
 
660
- # Raises <tt>ActiveRecord::PendingMigrationError</tt> error if any migrations are pending.
661
- def check_pending!(connection = Base.connection)
662
- raise ActiveRecord::PendingMigrationError if connection.migration_context.needs_migration?
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
663
693
  end
664
694
 
665
- def load_schema_if_pending!
666
- current_db_config = Base.connection_db_config
667
- all_configs = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env)
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 = []
699
+
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
704
+ end
705
+
706
+ migrations = pending_migrations.flatten
668
707
 
669
- needs_update = !all_configs.all? do |db_config|
670
- Tasks::DatabaseTasks.schema_up_to_date?(db_config, ActiveRecord.schema_format)
708
+ if migrations.any?
709
+ raise ActiveRecord::PendingMigrationError.new(pending_migrations: migrations)
671
710
  end
711
+ end
672
712
 
673
- if needs_update
713
+ def load_schema_if_pending!
714
+ if any_schema_needs_update?
674
715
  # Roundtrip to Rake to allow plugins to hook into database initialization.
675
716
  root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
717
+
676
718
  FileUtils.cd(root) do
677
- Base.clear_all_connections!
719
+ Base.connection_handler.clear_all_connections!(:all)
678
720
  system("bin/rails db:test:prepare")
679
721
  end
680
722
  end
681
723
 
682
- # Establish a new connection, the old database may be gone (db:test:prepare uses purge)
683
- Base.establish_connection(current_db_config)
684
-
685
- check_pending!
724
+ check_pending_migrations
686
725
  end
687
726
 
688
727
  def maintain_test_schema! # :nodoc:
@@ -707,6 +746,43 @@ module ActiveRecord
707
746
  def disable_ddl_transaction!
708
747
  @disable_ddl_transaction = true
709
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
710
786
  end
711
787
 
712
788
  def disable_ddl_transaction # :nodoc:
@@ -722,6 +798,10 @@ module ActiveRecord
722
798
  @connection = nil
723
799
  end
724
800
 
801
+ def execution_strategy
802
+ @execution_strategy ||= ActiveRecord.migration_strategy.new(self)
803
+ end
804
+
725
805
  self.verbose = true
726
806
  # instantiate the delegate object after initialize is defined
727
807
  self.delegate = new
@@ -733,7 +813,7 @@ module ActiveRecord
733
813
  # and create the table 'apples' on the way up, and the reverse
734
814
  # on the way down.
735
815
  #
736
- # class FixTLMigration < ActiveRecord::Migration[7.0]
816
+ # class FixTLMigration < ActiveRecord::Migration[7.1]
737
817
  # def change
738
818
  # revert do
739
819
  # create_table(:horses) do |t|
@@ -752,7 +832,7 @@ module ActiveRecord
752
832
  #
753
833
  # require_relative "20121212123456_tenderlove_migration"
754
834
  #
755
- # class FixupTLMigration < ActiveRecord::Migration[7.0]
835
+ # class FixupTLMigration < ActiveRecord::Migration[7.1]
756
836
  # def change
757
837
  # revert TenderloveMigration
758
838
  #
@@ -803,7 +883,7 @@ module ActiveRecord
803
883
  # when the three columns 'first_name', 'last_name' and 'full_name' exist,
804
884
  # even when migrating down:
805
885
  #
806
- # class SplitNameMigration < ActiveRecord::Migration[7.0]
886
+ # class SplitNameMigration < ActiveRecord::Migration[7.1]
807
887
  # def change
808
888
  # add_column :users, :first_name, :string
809
889
  # add_column :users, :last_name, :string
@@ -831,7 +911,7 @@ module ActiveRecord
831
911
  # In the following example, the new column +published+ will be given
832
912
  # the value +true+ for all existing records.
833
913
  #
834
- # class AddPublishedToPosts < ActiveRecord::Migration[7.0]
914
+ # class AddPublishedToPosts < ActiveRecord::Migration[7.1]
835
915
  # def change
836
916
  # add_column :posts, :published, :boolean, default: false
837
917
  # up_only do
@@ -884,7 +964,7 @@ module ActiveRecord
884
964
  end
885
965
 
886
966
  time = nil
887
- ActiveRecord::Base.connection_pool.with_connection do |conn|
967
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection.pool.with_connection do |conn|
888
968
  time = Benchmark.measure do
889
969
  exec_migration(conn, direction)
890
970
  end
@@ -909,6 +989,7 @@ module ActiveRecord
909
989
  end
910
990
  ensure
911
991
  @connection = nil
992
+ @execution_strategy = nil
912
993
  end
913
994
 
914
995
  def write(text = "")
@@ -947,7 +1028,7 @@ module ActiveRecord
947
1028
  end
948
1029
 
949
1030
  def connection
950
- @connection || ActiveRecord::Base.connection
1031
+ @connection || ActiveRecord::Tasks::DatabaseTasks.migration_connection
951
1032
  end
952
1033
 
953
1034
  def method_missing(method, *arguments, &block)
@@ -961,22 +1042,23 @@ module ActiveRecord
961
1042
  end
962
1043
  end
963
1044
  end
964
- return super unless connection.respond_to?(method)
965
- connection.send(method, *arguments, &block)
1045
+ return super unless execution_strategy.respond_to?(method)
1046
+ execution_strategy.send(method, *arguments, &block)
966
1047
  end
967
1048
  end
968
1049
  ruby2_keywords(:method_missing)
969
1050
 
970
1051
  def copy(destination, sources, options = {})
971
1052
  copied = []
972
- schema_migration = options[:schema_migration] || ActiveRecord::SchemaMigration
973
1053
 
974
1054
  FileUtils.mkdir_p(destination) unless File.exist?(destination)
1055
+ schema_migration = SchemaMigration::NullSchemaMigration.new
1056
+ internal_metadata = InternalMetadata::NullInternalMetadata.new
975
1057
 
976
- destination_migrations = ActiveRecord::MigrationContext.new(destination, schema_migration).migrations
1058
+ destination_migrations = ActiveRecord::MigrationContext.new(destination, schema_migration, internal_metadata).migrations
977
1059
  last = destination_migrations.last
978
1060
  sources.each do |scope, path|
979
- source_migrations = ActiveRecord::MigrationContext.new(path, schema_migration).migrations
1061
+ source_migrations = ActiveRecord::MigrationContext.new(path, schema_migration, internal_metadata).migrations
980
1062
 
981
1063
  source_migrations.each do |migration|
982
1064
  source = File.binread(migration.filename)
@@ -1037,7 +1119,7 @@ module ActiveRecord
1037
1119
  if ActiveRecord.timestamped_migrations
1038
1120
  [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % number].max
1039
1121
  else
1040
- SchemaMigration.normalize_migration_number(number)
1122
+ "%.3d" % number.to_i
1041
1123
  end
1042
1124
  end
1043
1125
 
@@ -1107,19 +1189,44 @@ module ActiveRecord
1107
1189
  end
1108
1190
  end
1109
1191
 
1192
+ # = \Migration \Context
1193
+ #
1110
1194
  # MigrationContext sets the context in which a migration is run.
1111
1195
  #
1112
1196
  # A migration context requires the path to the migrations is set
1113
1197
  # in the +migrations_paths+ parameter. Optionally a +schema_migration+
1114
- # class can be provided. For most applications, +SchemaMigration+ is
1115
- # sufficient. Multiple database applications need a +SchemaMigration+
1116
- # per primary database.
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.
1117
1201
  class MigrationContext
1118
- 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
1119
1226
 
1120
- def initialize(migrations_paths, schema_migration = SchemaMigration)
1121
1227
  @migrations_paths = migrations_paths
1122
- @schema_migration = schema_migration
1228
+ @schema_migration = schema_migration || SchemaMigration.new(connection)
1229
+ @internal_metadata = internal_metadata || InternalMetadata.new(connection)
1123
1230
  end
1124
1231
 
1125
1232
  # Runs the migrations in the +migrations_path+.
@@ -1163,7 +1270,7 @@ module ActiveRecord
1163
1270
  migrations
1164
1271
  end
1165
1272
 
1166
- Migrator.new(:up, selected_migrations, schema_migration, target_version).migrate
1273
+ Migrator.new(:up, selected_migrations, schema_migration, internal_metadata, target_version).migrate
1167
1274
  end
1168
1275
 
1169
1276
  def down(target_version = nil, &block) # :nodoc:
@@ -1173,20 +1280,20 @@ module ActiveRecord
1173
1280
  migrations
1174
1281
  end
1175
1282
 
1176
- Migrator.new(:down, selected_migrations, schema_migration, target_version).migrate
1283
+ Migrator.new(:down, selected_migrations, schema_migration, internal_metadata, target_version).migrate
1177
1284
  end
1178
1285
 
1179
1286
  def run(direction, target_version) # :nodoc:
1180
- Migrator.new(direction, migrations, schema_migration, target_version).run
1287
+ Migrator.new(direction, migrations, schema_migration, internal_metadata, target_version).run
1181
1288
  end
1182
1289
 
1183
1290
  def open # :nodoc:
1184
- Migrator.new(:up, migrations, schema_migration)
1291
+ Migrator.new(:up, migrations, schema_migration, internal_metadata)
1185
1292
  end
1186
1293
 
1187
1294
  def get_all_versions # :nodoc:
1188
1295
  if schema_migration.table_exists?
1189
- schema_migration.all_versions.map(&:to_i)
1296
+ schema_migration.integer_versions
1190
1297
  else
1191
1298
  []
1192
1299
  end
@@ -1245,16 +1352,20 @@ module ActiveRecord
1245
1352
  end
1246
1353
 
1247
1354
  def last_stored_environment # :nodoc:
1248
- return nil unless ActiveRecord::InternalMetadata.enabled?
1355
+ return nil unless connection.internal_metadata.enabled?
1249
1356
  return nil if current_version == 0
1250
- raise NoEnvironmentInSchemaError unless ActiveRecord::InternalMetadata.table_exists?
1357
+ raise NoEnvironmentInSchemaError unless connection.internal_metadata.table_exists?
1251
1358
 
1252
- environment = ActiveRecord::InternalMetadata[:environment]
1359
+ environment = connection.internal_metadata[:environment]
1253
1360
  raise NoEnvironmentInSchemaError unless environment
1254
1361
  environment
1255
1362
  end
1256
1363
 
1257
1364
  private
1365
+ def connection
1366
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection
1367
+ end
1368
+
1258
1369
  def migration_files
1259
1370
  paths = Array(migrations_paths)
1260
1371
  Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
@@ -1265,7 +1376,7 @@ module ActiveRecord
1265
1376
  end
1266
1377
 
1267
1378
  def move(direction, steps)
1268
- migrator = Migrator.new(direction, migrations, schema_migration)
1379
+ migrator = Migrator.new(direction, migrations, schema_migration, internal_metadata)
1269
1380
 
1270
1381
  if current_version != 0 && !migrator.current_migration
1271
1382
  raise UnknownMigrationVersionError.new(current_version)
@@ -1290,23 +1401,28 @@ module ActiveRecord
1290
1401
 
1291
1402
  # For cases where a table doesn't exist like loading from schema cache
1292
1403
  def current_version
1293
- 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
1294
1409
  end
1295
1410
  end
1296
1411
 
1297
1412
  self.migrations_paths = ["db/migrate"]
1298
1413
 
1299
- def initialize(direction, migrations, schema_migration, target_version = nil)
1414
+ def initialize(direction, migrations, schema_migration, internal_metadata, target_version = nil)
1300
1415
  @direction = direction
1301
1416
  @target_version = target_version
1302
1417
  @migrated_versions = nil
1303
1418
  @migrations = migrations
1304
1419
  @schema_migration = schema_migration
1420
+ @internal_metadata = internal_metadata
1305
1421
 
1306
1422
  validate(@migrations)
1307
1423
 
1308
1424
  @schema_migration.create_table
1309
- ActiveRecord::InternalMetadata.create_table
1425
+ @internal_metadata.create_table
1310
1426
  end
1311
1427
 
1312
1428
  def current_version
@@ -1359,18 +1475,21 @@ module ActiveRecord
1359
1475
  end
1360
1476
 
1361
1477
  def load_migrated
1362
- @migrated_versions = Set.new(@schema_migration.all_versions.map(&:to_i))
1478
+ @migrated_versions = Set.new(@schema_migration.integer_versions)
1363
1479
  end
1364
1480
 
1365
1481
  private
1482
+ def connection
1483
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection
1484
+ end
1485
+
1366
1486
  # Used for running a specific migration.
1367
1487
  def run_without_lock
1368
1488
  migration = migrations.detect { |m| m.version == @target_version }
1369
1489
  raise UnknownMigrationVersionError.new(@target_version) if migration.nil?
1370
- result = execute_migration_in_transaction(migration)
1371
1490
 
1372
1491
  record_environment
1373
- result
1492
+ execute_migration_in_transaction(migration)
1374
1493
  end
1375
1494
 
1376
1495
  # Used for running multiple migrations up to or down to a certain value.
@@ -1379,15 +1498,15 @@ module ActiveRecord
1379
1498
  raise UnknownMigrationVersionError.new(@target_version)
1380
1499
  end
1381
1500
 
1382
- result = runnable.each(&method(:execute_migration_in_transaction))
1383
1501
  record_environment
1384
- result
1502
+ runnable.each(&method(:execute_migration_in_transaction))
1385
1503
  end
1386
1504
 
1387
1505
  # Stores the current environment in the database.
1388
1506
  def record_environment
1389
1507
  return if down?
1390
- ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Base.connection.pool.db_config.env_name
1508
+
1509
+ @internal_metadata[:environment] = connection.pool.db_config.env_name
1391
1510
  end
1392
1511
 
1393
1512
  def ran?(migration)
@@ -1439,10 +1558,10 @@ module ActiveRecord
1439
1558
  def record_version_state_after_migrating(version)
1440
1559
  if down?
1441
1560
  migrated.delete(version)
1442
- @schema_migration.delete_by(version: version.to_s)
1561
+ @schema_migration.delete_version(version.to_s)
1443
1562
  else
1444
1563
  migrated << version
1445
- @schema_migration.create!(version: version.to_s)
1564
+ @schema_migration.create_version(version.to_s)
1446
1565
  end
1447
1566
  end
1448
1567
 
@@ -1457,50 +1576,38 @@ module ActiveRecord
1457
1576
  # Wrap the migration in a transaction only if supported by the adapter.
1458
1577
  def ddl_transaction(migration, &block)
1459
1578
  if use_transaction?(migration)
1460
- Base.transaction(&block)
1579
+ connection.transaction(&block)
1461
1580
  else
1462
1581
  yield
1463
1582
  end
1464
1583
  end
1465
1584
 
1466
1585
  def use_transaction?(migration)
1467
- !migration.disable_ddl_transaction && Base.connection.supports_ddl_transactions?
1586
+ !migration.disable_ddl_transaction && connection.supports_ddl_transactions?
1468
1587
  end
1469
1588
 
1470
1589
  def use_advisory_lock?
1471
- Base.connection.advisory_locks_enabled?
1590
+ connection.advisory_locks_enabled?
1472
1591
  end
1473
1592
 
1474
1593
  def with_advisory_lock
1475
1594
  lock_id = generate_migrator_advisory_lock_id
1476
1595
 
1477
- with_advisory_lock_connection do |connection|
1478
- got_lock = connection.get_advisory_lock(lock_id)
1479
- raise ConcurrentMigrationError unless got_lock
1480
- load_migrated # reload schema_migrations to be sure it wasn't changed by another process before we got the lock
1481
- yield
1482
- ensure
1483
- if got_lock && !connection.release_advisory_lock(lock_id)
1484
- raise ConcurrentMigrationError.new(
1485
- ConcurrentMigrationError::RELEASE_LOCK_FAILED_MESSAGE
1486
- )
1487
- end
1488
- end
1489
- end
1490
-
1491
- def with_advisory_lock_connection(&block)
1492
- pool = ActiveRecord::ConnectionAdapters::ConnectionHandler.new.establish_connection(
1493
- ActiveRecord::Base.connection_db_config
1494
- )
1495
-
1496
- pool.with_connection(&block)
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
1497
1600
  ensure
1498
- 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
1499
1606
  end
1500
1607
 
1501
1608
  MIGRATOR_SALT = 2053462845
1502
1609
  def generate_migrator_advisory_lock_id
1503
- db_name_hash = Zlib.crc32(Base.connection.current_database)
1610
+ db_name_hash = Zlib.crc32(connection.current_database)
1504
1611
  MIGRATOR_SALT * db_name_hash
1505
1612
  end
1506
1613
  end