activerecord 7.0.8 → 7.1.3.4
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 +1554 -1452
- 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 +20 -4
- 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 +31 -7
- 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 +313 -217
- 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 +74 -51
- 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 +62 -23
- 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 +262 -0
- data/lib/active_record/connection_adapters.rb +3 -1
- data/lib/active_record/connection_handling.rb +72 -95
- data/lib/active_record/core.rb +175 -153
- 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 +9 -4
- 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 +42 -18
- data/lib/active_record/encryption/encrypted_attribute_type.rb +21 -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 +112 -18
- 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 +135 -71
- data/lib/active_record/future_result.rb +31 -5
- data/lib/active_record/gem_version.rb +4 -4
- 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 +6 -8
- 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 +139 -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 +219 -111
- 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 +188 -37
- 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 +12 -6
- 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 +187 -63
- data/lib/active_record/relation/delegation.rb +23 -9
- 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 +91 -35
- data/lib/active_record/result.rb +19 -5
- data/lib/active_record/runtime_registry.rb +24 -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 +48 -12
- 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,15 +363,16 @@ module ActiveRecord
|
|
356
363
|
# == Irreversible transformations
|
357
364
|
#
|
358
365
|
# Some transformations are destructive in a manner that cannot be reversed.
|
359
|
-
# Migrations of that kind should raise an
|
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
|
+
#
|
375
|
+
# $ bin/rails generate migration MyNewMigration
|
368
376
|
#
|
369
377
|
# where MyNewMigration is the name of your migration. The generator will
|
370
378
|
# create an empty migration file <tt>timestamp_my_new_migration.rb</tt>
|
@@ -373,10 +381,10 @@ module ActiveRecord
|
|
373
381
|
#
|
374
382
|
# There is a special syntactic shortcut to generate migrations that add fields to a table.
|
375
383
|
#
|
376
|
-
# bin/rails generate migration add_fieldname_to_tablename fieldname:string
|
384
|
+
# $ bin/rails generate migration add_fieldname_to_tablename fieldname:string
|
377
385
|
#
|
378
386
|
# This will generate the file <tt>timestamp_add_fieldname_to_tablename.rb</tt>, which will look like this:
|
379
|
-
# class AddFieldnameToTablename < ActiveRecord::Migration[7.
|
387
|
+
# class AddFieldnameToTablename < ActiveRecord::Migration[7.1]
|
380
388
|
# def change
|
381
389
|
# add_column :tablenames, :fieldname, :string
|
382
390
|
# end
|
@@ -395,14 +403,14 @@ module ActiveRecord
|
|
395
403
|
# wish to rollback last few migrations. <tt>bin/rails db:rollback STEP=2</tt> will rollback
|
396
404
|
# the latest two migrations.
|
397
405
|
#
|
398
|
-
# If any of the migrations throw an
|
406
|
+
# If any of the migrations throw an ActiveRecord::IrreversibleMigration exception,
|
399
407
|
# that step will fail and you'll have some manual work to do.
|
400
408
|
#
|
401
409
|
# == More examples
|
402
410
|
#
|
403
411
|
# Not all migrations change the schema. Some just fix the data:
|
404
412
|
#
|
405
|
-
# class RemoveEmptyTags < ActiveRecord::Migration[7.
|
413
|
+
# class RemoveEmptyTags < ActiveRecord::Migration[7.1]
|
406
414
|
# def up
|
407
415
|
# Tag.all.each { |tag| tag.destroy if tag.pages.empty? }
|
408
416
|
# end
|
@@ -415,7 +423,7 @@ module ActiveRecord
|
|
415
423
|
#
|
416
424
|
# Others remove columns when they migrate up instead of down:
|
417
425
|
#
|
418
|
-
# class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[7.
|
426
|
+
# class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[7.1]
|
419
427
|
# def up
|
420
428
|
# remove_column :items, :incomplete_items_count
|
421
429
|
# remove_column :items, :completed_items_count
|
@@ -429,7 +437,7 @@ module ActiveRecord
|
|
429
437
|
#
|
430
438
|
# And sometimes you need to do something in SQL not abstracted directly by migrations:
|
431
439
|
#
|
432
|
-
# class MakeJoinUnique < ActiveRecord::Migration[7.
|
440
|
+
# class MakeJoinUnique < ActiveRecord::Migration[7.1]
|
433
441
|
# def up
|
434
442
|
# execute "ALTER TABLE `pages_linked_pages` ADD UNIQUE `page_id_linked_page_id` (`page_id`,`linked_page_id`)"
|
435
443
|
# end
|
@@ -446,7 +454,7 @@ module ActiveRecord
|
|
446
454
|
# <tt>Base#reset_column_information</tt> in order to ensure that the model has the
|
447
455
|
# latest column data from after the new column was added. Example:
|
448
456
|
#
|
449
|
-
# class AddPeopleSalary < ActiveRecord::Migration[7.
|
457
|
+
# class AddPeopleSalary < ActiveRecord::Migration[7.1]
|
450
458
|
# def up
|
451
459
|
# add_column :people, :salary, :integer
|
452
460
|
# Person.reset_column_information
|
@@ -482,7 +490,7 @@ module ActiveRecord
|
|
482
490
|
#
|
483
491
|
# == Timestamped Migrations
|
484
492
|
#
|
485
|
-
# By default, Rails generates migrations that look like:
|
493
|
+
# By default, \Rails generates migrations that look like:
|
486
494
|
#
|
487
495
|
# 20080717013526_your_migration_name.rb
|
488
496
|
#
|
@@ -504,7 +512,7 @@ module ActiveRecord
|
|
504
512
|
# To define a reversible migration, define the +change+ method in your
|
505
513
|
# migration like this:
|
506
514
|
#
|
507
|
-
# class TenderloveMigration < ActiveRecord::Migration[7.
|
515
|
+
# class TenderloveMigration < ActiveRecord::Migration[7.1]
|
508
516
|
# def change
|
509
517
|
# create_table(:horses) do |t|
|
510
518
|
# t.column :content, :text
|
@@ -521,11 +529,11 @@ module ActiveRecord
|
|
521
529
|
# as before.
|
522
530
|
#
|
523
531
|
# If a command cannot be reversed, an
|
524
|
-
#
|
532
|
+
# ActiveRecord::IrreversibleMigration exception will be raised when
|
525
533
|
# the migration is moving down.
|
526
534
|
#
|
527
535
|
# For a list of commands that are reversible, please see
|
528
|
-
#
|
536
|
+
# +ActiveRecord::Migration::CommandRecorder+.
|
529
537
|
#
|
530
538
|
# == Transactional Migrations
|
531
539
|
#
|
@@ -534,7 +542,7 @@ module ActiveRecord
|
|
534
542
|
# can't execute inside a transaction though, and for these situations
|
535
543
|
# you can turn the automatic transactions off.
|
536
544
|
#
|
537
|
-
# class ChangeEnum < ActiveRecord::Migration[7.
|
545
|
+
# class ChangeEnum < ActiveRecord::Migration[7.1]
|
538
546
|
# disable_ddl_transaction!
|
539
547
|
#
|
540
548
|
# def up
|
@@ -548,6 +556,8 @@ module ActiveRecord
|
|
548
556
|
autoload :CommandRecorder, "active_record/migration/command_recorder"
|
549
557
|
autoload :Compatibility, "active_record/migration/compatibility"
|
550
558
|
autoload :JoinTable, "active_record/migration/join_table"
|
559
|
+
autoload :ExecutionStrategy, "active_record/migration/execution_strategy"
|
560
|
+
autoload :DefaultStrategy, "active_record/migration/default_strategy"
|
551
561
|
|
552
562
|
# This must be defined before the inherited hook, below
|
553
563
|
class Current < Migration # :nodoc:
|
@@ -610,6 +620,13 @@ module ActiveRecord
|
|
610
620
|
|
611
621
|
MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/ # :nodoc:
|
612
622
|
|
623
|
+
def self.valid_version_format?(version_string) # :nodoc:
|
624
|
+
[
|
625
|
+
MigrationFilenameRegexp,
|
626
|
+
/\A\d(_?\d)*\z/ # integer with optional underscores
|
627
|
+
].any? { |pattern| pattern.match?(version_string) }
|
628
|
+
end
|
629
|
+
|
613
630
|
# This class is used to verify that all migrations have been run before
|
614
631
|
# loading a web page if <tt>config.active_record.migration_error</tt> is set to +:page_load+.
|
615
632
|
class CheckPending
|
@@ -624,7 +641,7 @@ module ActiveRecord
|
|
624
641
|
@mutex.synchronize do
|
625
642
|
@watcher ||= build_watcher do
|
626
643
|
@needs_check = true
|
627
|
-
ActiveRecord::Migration.
|
644
|
+
ActiveRecord::Migration.check_pending_migrations
|
628
645
|
@needs_check = false
|
629
646
|
end
|
630
647
|
|
@@ -640,12 +657,14 @@ module ActiveRecord
|
|
640
657
|
|
641
658
|
private
|
642
659
|
def build_watcher(&block)
|
643
|
-
|
660
|
+
current_environment = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
|
661
|
+
all_configs = ActiveRecord::Base.configurations.configs_for(env_name: current_environment)
|
662
|
+
paths = all_configs.flat_map { |config| config.migrations_paths || Migrator.migrations_paths }.uniq
|
644
663
|
@file_watcher.new([], paths.index_with(["rb"]), &block)
|
645
664
|
end
|
646
665
|
|
647
666
|
def connection
|
648
|
-
ActiveRecord::
|
667
|
+
ActiveRecord::Tasks::DatabaseTasks.migration_connection
|
649
668
|
end
|
650
669
|
end
|
651
670
|
|
@@ -657,32 +676,53 @@ module ActiveRecord
|
|
657
676
|
delegate || superclass.nearest_delegate
|
658
677
|
end
|
659
678
|
|
660
|
-
# Raises
|
661
|
-
|
662
|
-
|
679
|
+
# Raises ActiveRecord::PendingMigrationError error if any migrations are pending.
|
680
|
+
#
|
681
|
+
# This is deprecated in favor of +check_all_pending!+
|
682
|
+
def check_pending!(connection = ActiveRecord::Tasks::DatabaseTasks.migration_connection)
|
683
|
+
ActiveRecord.deprecator.warn(<<-MSG.squish)
|
684
|
+
The `check_pending!` method is deprecated in favor of `check_all_pending!`. The
|
685
|
+
new implementation will loop through all available database configurations and find
|
686
|
+
pending migrations. The prior implementation did not permit this.
|
687
|
+
MSG
|
688
|
+
|
689
|
+
pending_migrations = connection.migration_context.open.pending_migrations
|
690
|
+
|
691
|
+
if pending_migrations.any?
|
692
|
+
raise ActiveRecord::PendingMigrationError.new(pending_migrations: pending_migrations)
|
693
|
+
end
|
663
694
|
end
|
664
695
|
|
665
|
-
|
666
|
-
|
667
|
-
|
696
|
+
# Raises ActiveRecord::PendingMigrationError error if any migrations are pending
|
697
|
+
# for all database configurations in an environment.
|
698
|
+
def check_all_pending!
|
699
|
+
pending_migrations = []
|
700
|
+
|
701
|
+
ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: env) do |connection|
|
702
|
+
if pending = connection.migration_context.open.pending_migrations
|
703
|
+
pending_migrations << pending
|
704
|
+
end
|
705
|
+
end
|
668
706
|
|
669
|
-
|
670
|
-
|
707
|
+
migrations = pending_migrations.flatten
|
708
|
+
|
709
|
+
if migrations.any?
|
710
|
+
raise ActiveRecord::PendingMigrationError.new(pending_migrations: migrations)
|
671
711
|
end
|
712
|
+
end
|
672
713
|
|
673
|
-
|
714
|
+
def load_schema_if_pending!
|
715
|
+
if any_schema_needs_update?
|
674
716
|
# Roundtrip to Rake to allow plugins to hook into database initialization.
|
675
717
|
root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
|
718
|
+
|
676
719
|
FileUtils.cd(root) do
|
677
|
-
Base.clear_all_connections!
|
720
|
+
Base.connection_handler.clear_all_connections!(:all)
|
678
721
|
system("bin/rails db:test:prepare")
|
679
722
|
end
|
680
723
|
end
|
681
724
|
|
682
|
-
|
683
|
-
Base.establish_connection(current_db_config)
|
684
|
-
|
685
|
-
check_pending!
|
725
|
+
check_pending_migrations
|
686
726
|
end
|
687
727
|
|
688
728
|
def maintain_test_schema! # :nodoc:
|
@@ -707,6 +747,43 @@ module ActiveRecord
|
|
707
747
|
def disable_ddl_transaction!
|
708
748
|
@disable_ddl_transaction = true
|
709
749
|
end
|
750
|
+
|
751
|
+
def check_pending_migrations # :nodoc:
|
752
|
+
migrations = pending_migrations
|
753
|
+
|
754
|
+
if migrations.any?
|
755
|
+
raise ActiveRecord::PendingMigrationError.new(pending_migrations: migrations)
|
756
|
+
end
|
757
|
+
end
|
758
|
+
|
759
|
+
private
|
760
|
+
def any_schema_needs_update?
|
761
|
+
!db_configs_in_current_env.all? do |db_config|
|
762
|
+
Tasks::DatabaseTasks.schema_up_to_date?(db_config, ActiveRecord.schema_format)
|
763
|
+
end
|
764
|
+
end
|
765
|
+
|
766
|
+
def db_configs_in_current_env
|
767
|
+
ActiveRecord::Base.configurations.configs_for(env_name: env)
|
768
|
+
end
|
769
|
+
|
770
|
+
def pending_migrations
|
771
|
+
pending_migrations = []
|
772
|
+
|
773
|
+
ActiveRecord::Base.configurations.configs_for(env_name: env).each do |db_config|
|
774
|
+
ActiveRecord::PendingMigrationConnection.establish_temporary_connection(db_config) do |conn|
|
775
|
+
if pending = conn.migration_context.open.pending_migrations
|
776
|
+
pending_migrations << pending
|
777
|
+
end
|
778
|
+
end
|
779
|
+
end
|
780
|
+
|
781
|
+
pending_migrations.flatten
|
782
|
+
end
|
783
|
+
|
784
|
+
def env
|
785
|
+
ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
|
786
|
+
end
|
710
787
|
end
|
711
788
|
|
712
789
|
def disable_ddl_transaction # :nodoc:
|
@@ -722,6 +799,10 @@ module ActiveRecord
|
|
722
799
|
@connection = nil
|
723
800
|
end
|
724
801
|
|
802
|
+
def execution_strategy
|
803
|
+
@execution_strategy ||= ActiveRecord.migration_strategy.new(self)
|
804
|
+
end
|
805
|
+
|
725
806
|
self.verbose = true
|
726
807
|
# instantiate the delegate object after initialize is defined
|
727
808
|
self.delegate = new
|
@@ -733,7 +814,7 @@ module ActiveRecord
|
|
733
814
|
# and create the table 'apples' on the way up, and the reverse
|
734
815
|
# on the way down.
|
735
816
|
#
|
736
|
-
# class FixTLMigration < ActiveRecord::Migration[7.
|
817
|
+
# class FixTLMigration < ActiveRecord::Migration[7.1]
|
737
818
|
# def change
|
738
819
|
# revert do
|
739
820
|
# create_table(:horses) do |t|
|
@@ -752,7 +833,7 @@ module ActiveRecord
|
|
752
833
|
#
|
753
834
|
# require_relative "20121212123456_tenderlove_migration"
|
754
835
|
#
|
755
|
-
# class FixupTLMigration < ActiveRecord::Migration[7.
|
836
|
+
# class FixupTLMigration < ActiveRecord::Migration[7.1]
|
756
837
|
# def change
|
757
838
|
# revert TenderloveMigration
|
758
839
|
#
|
@@ -803,7 +884,7 @@ module ActiveRecord
|
|
803
884
|
# when the three columns 'first_name', 'last_name' and 'full_name' exist,
|
804
885
|
# even when migrating down:
|
805
886
|
#
|
806
|
-
# class SplitNameMigration < ActiveRecord::Migration[7.
|
887
|
+
# class SplitNameMigration < ActiveRecord::Migration[7.1]
|
807
888
|
# def change
|
808
889
|
# add_column :users, :first_name, :string
|
809
890
|
# add_column :users, :last_name, :string
|
@@ -831,7 +912,7 @@ module ActiveRecord
|
|
831
912
|
# In the following example, the new column +published+ will be given
|
832
913
|
# the value +true+ for all existing records.
|
833
914
|
#
|
834
|
-
# class AddPublishedToPosts < ActiveRecord::Migration[7.
|
915
|
+
# class AddPublishedToPosts < ActiveRecord::Migration[7.1]
|
835
916
|
# def change
|
836
917
|
# add_column :posts, :published, :boolean, default: false
|
837
918
|
# up_only do
|
@@ -884,7 +965,7 @@ module ActiveRecord
|
|
884
965
|
end
|
885
966
|
|
886
967
|
time = nil
|
887
|
-
ActiveRecord::
|
968
|
+
ActiveRecord::Tasks::DatabaseTasks.migration_connection.pool.with_connection do |conn|
|
888
969
|
time = Benchmark.measure do
|
889
970
|
exec_migration(conn, direction)
|
890
971
|
end
|
@@ -909,6 +990,7 @@ module ActiveRecord
|
|
909
990
|
end
|
910
991
|
ensure
|
911
992
|
@connection = nil
|
993
|
+
@execution_strategy = nil
|
912
994
|
end
|
913
995
|
|
914
996
|
def write(text = "")
|
@@ -947,7 +1029,7 @@ module ActiveRecord
|
|
947
1029
|
end
|
948
1030
|
|
949
1031
|
def connection
|
950
|
-
@connection || ActiveRecord::
|
1032
|
+
@connection || ActiveRecord::Tasks::DatabaseTasks.migration_connection
|
951
1033
|
end
|
952
1034
|
|
953
1035
|
def method_missing(method, *arguments, &block)
|
@@ -961,22 +1043,23 @@ module ActiveRecord
|
|
961
1043
|
end
|
962
1044
|
end
|
963
1045
|
end
|
964
|
-
return super unless
|
965
|
-
|
1046
|
+
return super unless execution_strategy.respond_to?(method)
|
1047
|
+
execution_strategy.send(method, *arguments, &block)
|
966
1048
|
end
|
967
1049
|
end
|
968
1050
|
ruby2_keywords(:method_missing)
|
969
1051
|
|
970
1052
|
def copy(destination, sources, options = {})
|
971
1053
|
copied = []
|
972
|
-
schema_migration = options[:schema_migration] || ActiveRecord::SchemaMigration
|
973
1054
|
|
974
1055
|
FileUtils.mkdir_p(destination) unless File.exist?(destination)
|
1056
|
+
schema_migration = SchemaMigration::NullSchemaMigration.new
|
1057
|
+
internal_metadata = InternalMetadata::NullInternalMetadata.new
|
975
1058
|
|
976
|
-
destination_migrations = ActiveRecord::MigrationContext.new(destination, schema_migration).migrations
|
1059
|
+
destination_migrations = ActiveRecord::MigrationContext.new(destination, schema_migration, internal_metadata).migrations
|
977
1060
|
last = destination_migrations.last
|
978
1061
|
sources.each do |scope, path|
|
979
|
-
source_migrations = ActiveRecord::MigrationContext.new(path, schema_migration).migrations
|
1062
|
+
source_migrations = ActiveRecord::MigrationContext.new(path, schema_migration, internal_metadata).migrations
|
980
1063
|
|
981
1064
|
source_migrations.each do |migration|
|
982
1065
|
source = File.binread(migration.filename)
|
@@ -1037,7 +1120,7 @@ module ActiveRecord
|
|
1037
1120
|
if ActiveRecord.timestamped_migrations
|
1038
1121
|
[Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % number].max
|
1039
1122
|
else
|
1040
|
-
|
1123
|
+
"%.3d" % number.to_i
|
1041
1124
|
end
|
1042
1125
|
end
|
1043
1126
|
|
@@ -1107,19 +1190,44 @@ module ActiveRecord
|
|
1107
1190
|
end
|
1108
1191
|
end
|
1109
1192
|
|
1193
|
+
# = \Migration \Context
|
1194
|
+
#
|
1110
1195
|
# MigrationContext sets the context in which a migration is run.
|
1111
1196
|
#
|
1112
1197
|
# A migration context requires the path to the migrations is set
|
1113
1198
|
# in the +migrations_paths+ parameter. Optionally a +schema_migration+
|
1114
|
-
# class can be provided.
|
1115
|
-
#
|
1116
|
-
#
|
1199
|
+
# class can be provided. Multiple database applications will instantiate
|
1200
|
+
# a +SchemaMigration+ object per database. From the Rake tasks, \Rails will
|
1201
|
+
# handle this for you.
|
1117
1202
|
class MigrationContext
|
1118
|
-
attr_reader :migrations_paths, :schema_migration
|
1203
|
+
attr_reader :migrations_paths, :schema_migration, :internal_metadata
|
1204
|
+
|
1205
|
+
def initialize(migrations_paths, schema_migration = nil, internal_metadata = nil)
|
1206
|
+
if schema_migration == SchemaMigration
|
1207
|
+
ActiveRecord.deprecator.warn(<<-MSG.squish)
|
1208
|
+
SchemaMigration no longer inherits from ActiveRecord::Base. If you want
|
1209
|
+
to use the default connection, remove this argument. If you want to use a
|
1210
|
+
specific connection, instantiate MigrationContext with the connection's schema
|
1211
|
+
migration, for example `MigrationContext.new(path, Dog.connection.schema_migration)`.
|
1212
|
+
MSG
|
1213
|
+
|
1214
|
+
schema_migration = nil
|
1215
|
+
end
|
1216
|
+
|
1217
|
+
if internal_metadata == InternalMetadata
|
1218
|
+
ActiveRecord.deprecator.warn(<<-MSG.squish)
|
1219
|
+
SchemaMigration no longer inherits from ActiveRecord::Base. If you want
|
1220
|
+
to use the default connection, remove this argument. If you want to use a
|
1221
|
+
specific connection, instantiate MigrationContext with the connection's internal
|
1222
|
+
metadata, for example `MigrationContext.new(path, nil, Dog.connection.internal_metadata)`.
|
1223
|
+
MSG
|
1224
|
+
|
1225
|
+
internal_metadata = nil
|
1226
|
+
end
|
1119
1227
|
|
1120
|
-
def initialize(migrations_paths, schema_migration = SchemaMigration)
|
1121
1228
|
@migrations_paths = migrations_paths
|
1122
|
-
@schema_migration = schema_migration
|
1229
|
+
@schema_migration = schema_migration || SchemaMigration.new(connection)
|
1230
|
+
@internal_metadata = internal_metadata || InternalMetadata.new(connection)
|
1123
1231
|
end
|
1124
1232
|
|
1125
1233
|
# Runs the migrations in the +migrations_path+.
|
@@ -1163,7 +1271,7 @@ module ActiveRecord
|
|
1163
1271
|
migrations
|
1164
1272
|
end
|
1165
1273
|
|
1166
|
-
Migrator.new(:up, selected_migrations, schema_migration, target_version).migrate
|
1274
|
+
Migrator.new(:up, selected_migrations, schema_migration, internal_metadata, target_version).migrate
|
1167
1275
|
end
|
1168
1276
|
|
1169
1277
|
def down(target_version = nil, &block) # :nodoc:
|
@@ -1173,20 +1281,20 @@ module ActiveRecord
|
|
1173
1281
|
migrations
|
1174
1282
|
end
|
1175
1283
|
|
1176
|
-
Migrator.new(:down, selected_migrations, schema_migration, target_version).migrate
|
1284
|
+
Migrator.new(:down, selected_migrations, schema_migration, internal_metadata, target_version).migrate
|
1177
1285
|
end
|
1178
1286
|
|
1179
1287
|
def run(direction, target_version) # :nodoc:
|
1180
|
-
Migrator.new(direction, migrations, schema_migration, target_version).run
|
1288
|
+
Migrator.new(direction, migrations, schema_migration, internal_metadata, target_version).run
|
1181
1289
|
end
|
1182
1290
|
|
1183
1291
|
def open # :nodoc:
|
1184
|
-
Migrator.new(:up, migrations, schema_migration)
|
1292
|
+
Migrator.new(:up, migrations, schema_migration, internal_metadata)
|
1185
1293
|
end
|
1186
1294
|
|
1187
1295
|
def get_all_versions # :nodoc:
|
1188
1296
|
if schema_migration.table_exists?
|
1189
|
-
schema_migration.
|
1297
|
+
schema_migration.integer_versions
|
1190
1298
|
else
|
1191
1299
|
[]
|
1192
1300
|
end
|
@@ -1245,16 +1353,20 @@ module ActiveRecord
|
|
1245
1353
|
end
|
1246
1354
|
|
1247
1355
|
def last_stored_environment # :nodoc:
|
1248
|
-
return nil unless
|
1356
|
+
return nil unless connection.internal_metadata.enabled?
|
1249
1357
|
return nil if current_version == 0
|
1250
|
-
raise NoEnvironmentInSchemaError unless
|
1358
|
+
raise NoEnvironmentInSchemaError unless connection.internal_metadata.table_exists?
|
1251
1359
|
|
1252
|
-
environment =
|
1360
|
+
environment = connection.internal_metadata[:environment]
|
1253
1361
|
raise NoEnvironmentInSchemaError unless environment
|
1254
1362
|
environment
|
1255
1363
|
end
|
1256
1364
|
|
1257
1365
|
private
|
1366
|
+
def connection
|
1367
|
+
ActiveRecord::Tasks::DatabaseTasks.migration_connection
|
1368
|
+
end
|
1369
|
+
|
1258
1370
|
def migration_files
|
1259
1371
|
paths = Array(migrations_paths)
|
1260
1372
|
Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
|
@@ -1265,7 +1377,7 @@ module ActiveRecord
|
|
1265
1377
|
end
|
1266
1378
|
|
1267
1379
|
def move(direction, steps)
|
1268
|
-
migrator = Migrator.new(direction, migrations, schema_migration)
|
1380
|
+
migrator = Migrator.new(direction, migrations, schema_migration, internal_metadata)
|
1269
1381
|
|
1270
1382
|
if current_version != 0 && !migrator.current_migration
|
1271
1383
|
raise UnknownMigrationVersionError.new(current_version)
|
@@ -1290,23 +1402,28 @@ module ActiveRecord
|
|
1290
1402
|
|
1291
1403
|
# For cases where a table doesn't exist like loading from schema cache
|
1292
1404
|
def current_version
|
1293
|
-
|
1405
|
+
connection = ActiveRecord::Tasks::DatabaseTasks.migration_connection
|
1406
|
+
schema_migration = SchemaMigration.new(connection)
|
1407
|
+
internal_metadata = InternalMetadata.new(connection)
|
1408
|
+
|
1409
|
+
MigrationContext.new(migrations_paths, schema_migration, internal_metadata).current_version
|
1294
1410
|
end
|
1295
1411
|
end
|
1296
1412
|
|
1297
1413
|
self.migrations_paths = ["db/migrate"]
|
1298
1414
|
|
1299
|
-
def initialize(direction, migrations, schema_migration, target_version = nil)
|
1415
|
+
def initialize(direction, migrations, schema_migration, internal_metadata, target_version = nil)
|
1300
1416
|
@direction = direction
|
1301
1417
|
@target_version = target_version
|
1302
1418
|
@migrated_versions = nil
|
1303
1419
|
@migrations = migrations
|
1304
1420
|
@schema_migration = schema_migration
|
1421
|
+
@internal_metadata = internal_metadata
|
1305
1422
|
|
1306
1423
|
validate(@migrations)
|
1307
1424
|
|
1308
1425
|
@schema_migration.create_table
|
1309
|
-
|
1426
|
+
@internal_metadata.create_table
|
1310
1427
|
end
|
1311
1428
|
|
1312
1429
|
def current_version
|
@@ -1359,18 +1476,21 @@ module ActiveRecord
|
|
1359
1476
|
end
|
1360
1477
|
|
1361
1478
|
def load_migrated
|
1362
|
-
@migrated_versions = Set.new(@schema_migration.
|
1479
|
+
@migrated_versions = Set.new(@schema_migration.integer_versions)
|
1363
1480
|
end
|
1364
1481
|
|
1365
1482
|
private
|
1483
|
+
def connection
|
1484
|
+
ActiveRecord::Tasks::DatabaseTasks.migration_connection
|
1485
|
+
end
|
1486
|
+
|
1366
1487
|
# Used for running a specific migration.
|
1367
1488
|
def run_without_lock
|
1368
1489
|
migration = migrations.detect { |m| m.version == @target_version }
|
1369
1490
|
raise UnknownMigrationVersionError.new(@target_version) if migration.nil?
|
1370
|
-
result = execute_migration_in_transaction(migration)
|
1371
1491
|
|
1372
1492
|
record_environment
|
1373
|
-
|
1493
|
+
execute_migration_in_transaction(migration)
|
1374
1494
|
end
|
1375
1495
|
|
1376
1496
|
# Used for running multiple migrations up to or down to a certain value.
|
@@ -1379,15 +1499,15 @@ module ActiveRecord
|
|
1379
1499
|
raise UnknownMigrationVersionError.new(@target_version)
|
1380
1500
|
end
|
1381
1501
|
|
1382
|
-
result = runnable.each(&method(:execute_migration_in_transaction))
|
1383
1502
|
record_environment
|
1384
|
-
|
1503
|
+
runnable.each(&method(:execute_migration_in_transaction))
|
1385
1504
|
end
|
1386
1505
|
|
1387
1506
|
# Stores the current environment in the database.
|
1388
1507
|
def record_environment
|
1389
1508
|
return if down?
|
1390
|
-
|
1509
|
+
|
1510
|
+
@internal_metadata[:environment] = connection.pool.db_config.env_name
|
1391
1511
|
end
|
1392
1512
|
|
1393
1513
|
def ran?(migration)
|
@@ -1439,10 +1559,10 @@ module ActiveRecord
|
|
1439
1559
|
def record_version_state_after_migrating(version)
|
1440
1560
|
if down?
|
1441
1561
|
migrated.delete(version)
|
1442
|
-
@schema_migration.
|
1562
|
+
@schema_migration.delete_version(version.to_s)
|
1443
1563
|
else
|
1444
1564
|
migrated << version
|
1445
|
-
@schema_migration.
|
1565
|
+
@schema_migration.create_version(version.to_s)
|
1446
1566
|
end
|
1447
1567
|
end
|
1448
1568
|
|
@@ -1457,50 +1577,38 @@ module ActiveRecord
|
|
1457
1577
|
# Wrap the migration in a transaction only if supported by the adapter.
|
1458
1578
|
def ddl_transaction(migration, &block)
|
1459
1579
|
if use_transaction?(migration)
|
1460
|
-
|
1580
|
+
connection.transaction(&block)
|
1461
1581
|
else
|
1462
1582
|
yield
|
1463
1583
|
end
|
1464
1584
|
end
|
1465
1585
|
|
1466
1586
|
def use_transaction?(migration)
|
1467
|
-
!migration.disable_ddl_transaction &&
|
1587
|
+
!migration.disable_ddl_transaction && connection.supports_ddl_transactions?
|
1468
1588
|
end
|
1469
1589
|
|
1470
1590
|
def use_advisory_lock?
|
1471
|
-
|
1591
|
+
connection.advisory_locks_enabled?
|
1472
1592
|
end
|
1473
1593
|
|
1474
1594
|
def with_advisory_lock
|
1475
1595
|
lock_id = generate_migrator_advisory_lock_id
|
1476
1596
|
|
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)
|
1597
|
+
got_lock = connection.get_advisory_lock(lock_id)
|
1598
|
+
raise ConcurrentMigrationError unless got_lock
|
1599
|
+
load_migrated # reload schema_migrations to be sure it wasn't changed by another process before we got the lock
|
1600
|
+
yield
|
1497
1601
|
ensure
|
1498
|
-
|
1602
|
+
if got_lock && !connection.release_advisory_lock(lock_id)
|
1603
|
+
raise ConcurrentMigrationError.new(
|
1604
|
+
ConcurrentMigrationError::RELEASE_LOCK_FAILED_MESSAGE
|
1605
|
+
)
|
1606
|
+
end
|
1499
1607
|
end
|
1500
1608
|
|
1501
1609
|
MIGRATOR_SALT = 2053462845
|
1502
1610
|
def generate_migrator_advisory_lock_id
|
1503
|
-
db_name_hash = Zlib.crc32(
|
1611
|
+
db_name_hash = Zlib.crc32(connection.current_database)
|
1504
1612
|
MIGRATOR_SALT * db_name_hash
|
1505
1613
|
end
|
1506
1614
|
end
|