activerecord 7.0.8 → 7.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1460 -1477
- data/MIT-LICENSE +1 -1
- data/README.rdoc +16 -16
- data/lib/active_record/aggregations.rb +16 -13
- data/lib/active_record/association_relation.rb +1 -1
- data/lib/active_record/associations/association.rb +18 -3
- data/lib/active_record/associations/association_scope.rb +16 -9
- data/lib/active_record/associations/belongs_to_association.rb +14 -6
- data/lib/active_record/associations/builder/association.rb +3 -3
- data/lib/active_record/associations/builder/belongs_to.rb +21 -8
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
- data/lib/active_record/associations/builder/singular_association.rb +4 -0
- data/lib/active_record/associations/collection_association.rb +15 -9
- data/lib/active_record/associations/collection_proxy.rb +15 -10
- data/lib/active_record/associations/foreign_association.rb +10 -3
- data/lib/active_record/associations/has_many_association.rb +20 -13
- data/lib/active_record/associations/has_many_through_association.rb +10 -6
- data/lib/active_record/associations/has_one_association.rb +10 -3
- data/lib/active_record/associations/join_dependency.rb +10 -8
- data/lib/active_record/associations/preloader/association.rb +27 -6
- data/lib/active_record/associations/preloader.rb +13 -10
- data/lib/active_record/associations/singular_association.rb +1 -1
- data/lib/active_record/associations/through_association.rb +22 -11
- data/lib/active_record/associations.rb +312 -216
- data/lib/active_record/attribute_assignment.rb +0 -2
- data/lib/active_record/attribute_methods/before_type_cast.rb +17 -0
- data/lib/active_record/attribute_methods/dirty.rb +52 -34
- data/lib/active_record/attribute_methods/primary_key.rb +76 -24
- data/lib/active_record/attribute_methods/query.rb +28 -16
- data/lib/active_record/attribute_methods/read.rb +18 -5
- data/lib/active_record/attribute_methods/serialization.rb +150 -31
- data/lib/active_record/attribute_methods/write.rb +3 -3
- data/lib/active_record/attribute_methods.rb +105 -21
- data/lib/active_record/attributes.rb +3 -3
- data/lib/active_record/autosave_association.rb +55 -9
- data/lib/active_record/base.rb +7 -2
- data/lib/active_record/callbacks.rb +10 -24
- data/lib/active_record/coders/column_serializer.rb +61 -0
- data/lib/active_record/coders/json.rb +1 -1
- data/lib/active_record/coders/yaml_column.rb +70 -42
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +163 -88
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +3 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +63 -43
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +129 -31
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +60 -22
- data/lib/active_record/connection_adapters/abstract/quoting.rb +41 -6
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +18 -4
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +137 -11
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +289 -124
- data/lib/active_record/connection_adapters/abstract/transaction.rb +287 -58
- data/lib/active_record/connection_adapters/abstract_adapter.rb +511 -91
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +207 -108
- data/lib/active_record/connection_adapters/column.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +22 -143
- data/lib/active_record/connection_adapters/mysql/quoting.rb +16 -12
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +6 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +18 -13
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +151 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +98 -53
- data/lib/active_record/connection_adapters/pool_config.rb +14 -5
- data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +14 -3
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +74 -40
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +11 -2
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +10 -6
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +3 -9
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -6
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +131 -2
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +53 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +361 -60
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +353 -192
- data/lib/active_record/connection_adapters/schema_cache.rb +287 -59
- data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +52 -39
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +4 -3
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +1 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +26 -7
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +209 -79
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +254 -0
- data/lib/active_record/connection_adapters.rb +3 -1
- data/lib/active_record/connection_handling.rb +71 -94
- data/lib/active_record/core.rb +140 -151
- data/lib/active_record/counter_cache.rb +46 -25
- data/lib/active_record/database_configurations/database_config.rb +9 -3
- data/lib/active_record/database_configurations/hash_config.rb +22 -12
- data/lib/active_record/database_configurations/url_config.rb +17 -11
- data/lib/active_record/database_configurations.rb +86 -33
- data/lib/active_record/delegated_type.rb +8 -3
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +2 -0
- data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +4 -1
- data/lib/active_record/encryption/config.rb +25 -1
- data/lib/active_record/encryption/configurable.rb +12 -19
- data/lib/active_record/encryption/context.rb +10 -3
- data/lib/active_record/encryption/contexts.rb +5 -1
- data/lib/active_record/encryption/derived_secret_key_provider.rb +8 -2
- data/lib/active_record/encryption/encryptable_record.rb +36 -18
- data/lib/active_record/encryption/encrypted_attribute_type.rb +17 -6
- data/lib/active_record/encryption/extended_deterministic_queries.rb +66 -69
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +3 -3
- data/lib/active_record/encryption/key_generator.rb +12 -1
- data/lib/active_record/encryption/message_serializer.rb +2 -0
- data/lib/active_record/encryption/properties.rb +3 -3
- data/lib/active_record/encryption/scheme.rb +19 -22
- data/lib/active_record/encryption.rb +1 -0
- data/lib/active_record/enum.rb +112 -28
- data/lib/active_record/errors.rb +108 -15
- data/lib/active_record/explain.rb +23 -3
- data/lib/active_record/fixture_set/model_metadata.rb +14 -4
- data/lib/active_record/fixture_set/render_context.rb +2 -0
- data/lib/active_record/fixture_set/table_row.rb +29 -8
- data/lib/active_record/fixtures.rb +119 -71
- data/lib/active_record/future_result.rb +30 -5
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +30 -16
- data/lib/active_record/insert_all.rb +57 -10
- data/lib/active_record/integration.rb +8 -8
- data/lib/active_record/internal_metadata.rb +120 -30
- data/lib/active_record/locking/pessimistic.rb +5 -2
- data/lib/active_record/log_subscriber.rb +29 -12
- data/lib/active_record/marshalling.rb +56 -0
- data/lib/active_record/message_pack.rb +124 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +4 -0
- data/lib/active_record/middleware/database_selector.rb +5 -7
- data/lib/active_record/middleware/shard_selector.rb +3 -1
- data/lib/active_record/migration/command_recorder.rb +104 -5
- data/lib/active_record/migration/compatibility.rb +131 -5
- data/lib/active_record/migration/default_strategy.rb +23 -0
- data/lib/active_record/migration/execution_strategy.rb +19 -0
- data/lib/active_record/migration/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +216 -109
- data/lib/active_record/model_schema.rb +64 -44
- data/lib/active_record/nested_attributes.rb +24 -6
- data/lib/active_record/normalization.rb +167 -0
- data/lib/active_record/persistence.rb +184 -34
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +3 -21
- data/lib/active_record/query_logs.rb +77 -52
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +15 -2
- data/lib/active_record/railtie.rb +109 -47
- data/lib/active_record/railties/controller_runtime.rb +10 -5
- data/lib/active_record/railties/databases.rake +142 -148
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +32 -5
- data/lib/active_record/reflection.rb +174 -44
- data/lib/active_record/relation/batches/batch_enumerator.rb +5 -3
- data/lib/active_record/relation/batches.rb +190 -61
- data/lib/active_record/relation/calculations.rb +160 -63
- data/lib/active_record/relation/delegation.rb +22 -8
- data/lib/active_record/relation/finder_methods.rb +77 -16
- data/lib/active_record/relation/merger.rb +2 -0
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +11 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -6
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
- data/lib/active_record/relation/predicate_builder.rb +26 -14
- data/lib/active_record/relation/query_attribute.rb +2 -1
- data/lib/active_record/relation/query_methods.rb +352 -63
- data/lib/active_record/relation/spawn_methods.rb +18 -1
- data/lib/active_record/relation.rb +76 -35
- data/lib/active_record/result.rb +19 -5
- data/lib/active_record/runtime_registry.rb +10 -1
- data/lib/active_record/sanitization.rb +51 -11
- data/lib/active_record/schema.rb +2 -3
- data/lib/active_record/schema_dumper.rb +46 -7
- data/lib/active_record/schema_migration.rb +68 -33
- data/lib/active_record/scoping/default.rb +15 -5
- data/lib/active_record/scoping/named.rb +2 -2
- data/lib/active_record/scoping.rb +2 -1
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +21 -3
- data/lib/active_record/signed_id.rb +7 -5
- data/lib/active_record/store.rb +8 -8
- data/lib/active_record/suppressor.rb +3 -1
- data/lib/active_record/table_metadata.rb +10 -1
- data/lib/active_record/tasks/database_tasks.rb +127 -105
- data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
- data/lib/active_record/tasks/postgresql_database_tasks.rb +16 -13
- data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
- data/lib/active_record/test_fixtures.rb +113 -96
- data/lib/active_record/timestamp.rb +27 -15
- data/lib/active_record/token_for.rb +113 -0
- data/lib/active_record/touch_later.rb +11 -6
- data/lib/active_record/transactions.rb +36 -10
- data/lib/active_record/type/adapter_specific_registry.rb +1 -8
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/time.rb +4 -0
- data/lib/active_record/validations/absence.rb +1 -1
- data/lib/active_record/validations/numericality.rb +5 -4
- data/lib/active_record/validations/presence.rb +5 -28
- data/lib/active_record/validations/uniqueness.rb +47 -2
- data/lib/active_record/validations.rb +8 -4
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +121 -16
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.rb +4 -0
- data/lib/arel/nodes/binary.rb +6 -1
- data/lib/arel/nodes/bound_sql_literal.rb +61 -0
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/homogeneous_in.rb +1 -9
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/node.rb +111 -2
- data/lib/arel/nodes/sql_literal.rb +6 -0
- data/lib/arel/nodes/table_alias.rb +4 -0
- data/lib/arel/nodes.rb +4 -0
- data/lib/arel/predications.rb +2 -0
- data/lib/arel/table.rb +9 -5
- data/lib/arel/visitors/mysql.rb +8 -1
- data/lib/arel/visitors/to_sql.rb +81 -17
- data/lib/arel/visitors/visitor.rb +2 -2
- data/lib/arel.rb +16 -2
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- data/lib/rails/generators/active_record/migration.rb +3 -1
- data/lib/rails/generators/active_record/model/USAGE +113 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
- metadata +47 -11
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
- 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.
|
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.
|
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.
|
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.
|
141
|
-
|
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
|
-
|
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.
|
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.
|
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.
|
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
|
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.
|
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
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|
-
#
|
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
|
-
#
|
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.
|
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.
|
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
|
-
|
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::
|
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
|
661
|
-
|
662
|
-
|
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
|
-
|
666
|
-
|
667
|
-
|
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
|
-
|
670
|
-
|
708
|
+
if migrations.any?
|
709
|
+
raise ActiveRecord::PendingMigrationError.new(pending_migrations: migrations)
|
671
710
|
end
|
711
|
+
end
|
672
712
|
|
673
|
-
|
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
|
-
|
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.
|
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.
|
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.
|
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.
|
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::
|
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::
|
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
|
965
|
-
|
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
|
-
|
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.
|
1115
|
-
#
|
1116
|
-
#
|
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.
|
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
|
1355
|
+
return nil unless connection.internal_metadata.enabled?
|
1249
1356
|
return nil if current_version == 0
|
1250
|
-
raise NoEnvironmentInSchemaError unless
|
1357
|
+
raise NoEnvironmentInSchemaError unless connection.internal_metadata.table_exists?
|
1251
1358
|
|
1252
|
-
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
|
-
|
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
|
-
|
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.
|
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
|
-
|
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
|
-
|
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
|
-
|
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.
|
1561
|
+
@schema_migration.delete_version(version.to_s)
|
1443
1562
|
else
|
1444
1563
|
migrated << version
|
1445
|
-
@schema_migration.
|
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
|
-
|
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 &&
|
1586
|
+
!migration.disable_ddl_transaction && connection.supports_ddl_transactions?
|
1468
1587
|
end
|
1469
1588
|
|
1470
1589
|
def use_advisory_lock?
|
1471
|
-
|
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
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
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
|
-
|
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(
|
1610
|
+
db_name_hash = Zlib.crc32(connection.current_database)
|
1504
1611
|
MIGRATOR_SALT * db_name_hash
|
1505
1612
|
end
|
1506
1613
|
end
|