activerecord 7.1.5.1 → 8.0.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 +369 -2484
- data/README.rdoc +15 -15
- data/examples/performance.rb +2 -2
- data/lib/active_record/association_relation.rb +2 -1
- data/lib/active_record/associations/alias_tracker.rb +31 -23
- data/lib/active_record/associations/association.rb +43 -12
- data/lib/active_record/associations/belongs_to_association.rb +21 -8
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
- data/lib/active_record/associations/builder/association.rb +7 -6
- data/lib/active_record/associations/builder/belongs_to.rb +1 -0
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -2
- data/lib/active_record/associations/builder/has_many.rb +3 -4
- data/lib/active_record/associations/builder/has_one.rb +3 -4
- data/lib/active_record/associations/collection_association.rb +17 -9
- data/lib/active_record/associations/collection_proxy.rb +14 -1
- data/lib/active_record/associations/disable_joins_association_scope.rb +1 -1
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +10 -3
- data/lib/active_record/associations/join_dependency/join_association.rb +1 -1
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +4 -3
- data/lib/active_record/associations/preloader/branch.rb +7 -1
- data/lib/active_record/associations/preloader/through_association.rb +1 -3
- data/lib/active_record/associations/singular_association.rb +14 -3
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +92 -295
- data/lib/active_record/asynchronous_queries_tracker.rb +28 -24
- data/lib/active_record/attribute_assignment.rb +0 -2
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/primary_key.rb +25 -61
- data/lib/active_record/attribute_methods/read.rb +1 -13
- data/lib/active_record/attribute_methods/serialization.rb +4 -24
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +9 -18
- data/lib/active_record/attribute_methods.rb +71 -75
- data/lib/active_record/attributes.rb +63 -49
- data/lib/active_record/autosave_association.rb +92 -57
- data/lib/active_record/base.rb +2 -3
- data/lib/active_record/callbacks.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +48 -122
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +286 -77
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +119 -55
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +197 -76
- data/lib/active_record/connection_adapters/abstract/quoting.rb +66 -92
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +12 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +48 -12
- data/lib/active_record/connection_adapters/abstract/transaction.rb +140 -67
- data/lib/active_record/connection_adapters/abstract_adapter.rb +85 -90
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +71 -52
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +9 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -57
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +2 -8
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +56 -45
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +92 -101
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +13 -31
- data/lib/active_record/connection_adapters/pool_config.rb +14 -13
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +86 -41
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +10 -0
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +58 -58
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -4
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +1 -11
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +36 -20
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +75 -28
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +73 -113
- data/lib/active_record/connection_adapters/schema_cache.rb +124 -131
- data/lib/active_record/connection_adapters/sqlite3/column.rb +14 -1
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +81 -97
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +57 -46
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +13 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +29 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +35 -3
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +183 -87
- data/lib/active_record/connection_adapters/statement_pool.rb +4 -2
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +39 -69
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +19 -65
- data/lib/active_record/connection_adapters.rb +65 -0
- data/lib/active_record/connection_handling.rb +74 -37
- data/lib/active_record/core.rb +132 -51
- data/lib/active_record/counter_cache.rb +19 -10
- data/lib/active_record/database_configurations/connection_url_resolver.rb +9 -2
- data/lib/active_record/database_configurations/database_config.rb +23 -4
- data/lib/active_record/database_configurations/hash_config.rb +46 -34
- data/lib/active_record/database_configurations/url_config.rb +20 -1
- data/lib/active_record/database_configurations.rb +1 -1
- data/lib/active_record/delegated_type.rb +41 -17
- data/lib/active_record/dynamic_matchers.rb +2 -2
- data/lib/active_record/encryption/config.rb +3 -1
- data/lib/active_record/encryption/encryptable_record.rb +7 -7
- data/lib/active_record/encryption/encrypted_attribute_type.rb +33 -4
- data/lib/active_record/encryption/encryptor.rb +28 -6
- data/lib/active_record/encryption/extended_deterministic_queries.rb +4 -2
- data/lib/active_record/encryption/key_provider.rb +1 -1
- data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
- data/lib/active_record/encryption/message_serializer.rb +4 -0
- data/lib/active_record/encryption/null_encryptor.rb +4 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
- data/lib/active_record/encryption/scheme.rb +8 -1
- data/lib/active_record/enum.rb +20 -16
- data/lib/active_record/errors.rb +54 -20
- data/lib/active_record/explain.rb +13 -24
- data/lib/active_record/fixtures.rb +37 -33
- data/lib/active_record/future_result.rb +21 -13
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +4 -2
- data/lib/active_record/insert_all.rb +19 -16
- data/lib/active_record/integration.rb +4 -1
- data/lib/active_record/internal_metadata.rb +48 -34
- data/lib/active_record/locking/optimistic.rb +8 -7
- data/lib/active_record/log_subscriber.rb +5 -32
- data/lib/active_record/message_pack.rb +1 -1
- data/lib/active_record/migration/command_recorder.rb +33 -14
- data/lib/active_record/migration/compatibility.rb +8 -3
- data/lib/active_record/migration/default_strategy.rb +4 -5
- data/lib/active_record/migration/pending_migration_connection.rb +2 -2
- data/lib/active_record/migration.rb +104 -98
- data/lib/active_record/model_schema.rb +32 -70
- data/lib/active_record/nested_attributes.rb +15 -9
- data/lib/active_record/normalization.rb +3 -7
- data/lib/active_record/persistence.rb +127 -451
- data/lib/active_record/query_cache.rb +19 -8
- data/lib/active_record/query_logs.rb +104 -37
- data/lib/active_record/query_logs_formatter.rb +17 -28
- data/lib/active_record/querying.rb +24 -12
- data/lib/active_record/railtie.rb +26 -68
- data/lib/active_record/railties/controller_runtime.rb +13 -4
- data/lib/active_record/railties/databases.rake +43 -61
- data/lib/active_record/reflection.rb +112 -53
- data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
- data/lib/active_record/relation/batches.rb +138 -72
- data/lib/active_record/relation/calculations.rb +122 -82
- data/lib/active_record/relation/delegation.rb +30 -22
- data/lib/active_record/relation/finder_methods.rb +32 -18
- data/lib/active_record/relation/merger.rb +12 -14
- data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +10 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -1
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +4 -3
- data/lib/active_record/relation/predicate_builder.rb +16 -3
- data/lib/active_record/relation/query_attribute.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +317 -101
- data/lib/active_record/relation/spawn_methods.rb +3 -19
- data/lib/active_record/relation/where_clause.rb +7 -19
- data/lib/active_record/relation.rb +561 -119
- data/lib/active_record/result.rb +95 -46
- data/lib/active_record/runtime_registry.rb +39 -0
- data/lib/active_record/sanitization.rb +31 -25
- data/lib/active_record/schema.rb +8 -6
- data/lib/active_record/schema_dumper.rb +53 -20
- data/lib/active_record/schema_migration.rb +31 -14
- data/lib/active_record/scoping/named.rb +6 -2
- data/lib/active_record/signed_id.rb +24 -4
- data/lib/active_record/statement_cache.rb +19 -19
- data/lib/active_record/store.rb +7 -3
- data/lib/active_record/table_metadata.rb +2 -13
- data/lib/active_record/tasks/database_tasks.rb +87 -58
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -3
- data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/sqlite_database_tasks.rb +4 -3
- data/lib/active_record/test_fixtures.rb +98 -89
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +2 -2
- data/lib/active_record/token_for.rb +22 -12
- data/lib/active_record/touch_later.rb +1 -1
- data/lib/active_record/transaction.rb +132 -0
- data/lib/active_record/transactions.rb +72 -17
- data/lib/active_record/translation.rb +0 -2
- data/lib/active_record/type/serialized.rb +1 -3
- data/lib/active_record/type_caster/connection.rb +4 -4
- data/lib/active_record/validations/associated.rb +9 -3
- data/lib/active_record/validations/uniqueness.rb +23 -18
- data/lib/active_record/validations.rb +4 -1
- data/lib/active_record.rb +138 -57
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/collectors/bind.rb +4 -2
- data/lib/arel/collectors/composite.rb +7 -0
- data/lib/arel/collectors/sql_string.rb +2 -2
- data/lib/arel/collectors/substitute_binds.rb +3 -3
- data/lib/arel/nodes/binary.rb +1 -7
- data/lib/arel/nodes/bound_sql_literal.rb +9 -5
- data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
- data/lib/arel/nodes/node.rb +5 -4
- data/lib/arel/nodes/sql_literal.rb +8 -1
- data/lib/arel/nodes.rb +2 -2
- data/lib/arel/predications.rb +1 -1
- data/lib/arel/select_manager.rb +1 -1
- data/lib/arel/table.rb +3 -7
- data/lib/arel/tree_manager.rb +3 -2
- data/lib/arel/update_manager.rb +2 -1
- data/lib/arel/visitors/dot.rb +1 -0
- data/lib/arel/visitors/mysql.rb +9 -4
- data/lib/arel/visitors/postgresql.rb +1 -12
- data/lib/arel/visitors/sqlite.rb +25 -0
- data/lib/arel/visitors/to_sql.rb +29 -16
- data/lib/arel.rb +7 -3
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
- metadata +18 -16
- data/lib/active_record/relation/record_fetch_warning.rb +0 -49
@@ -1,8 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "benchmark"
|
4
|
-
require "set"
|
5
|
-
require "zlib"
|
6
3
|
require "active_support/core_ext/array/access"
|
7
4
|
require "active_support/core_ext/enumerable"
|
8
5
|
require "active_support/core_ext/module/attribute_accessors"
|
@@ -21,7 +18,7 @@ module ActiveRecord
|
|
21
18
|
# For example the following migration is not reversible.
|
22
19
|
# Rolling back this migration will raise an ActiveRecord::IrreversibleMigration error.
|
23
20
|
#
|
24
|
-
# class IrreversibleMigrationExample < ActiveRecord::Migration[
|
21
|
+
# class IrreversibleMigrationExample < ActiveRecord::Migration[8.0]
|
25
22
|
# def change
|
26
23
|
# create_table :distributors do |t|
|
27
24
|
# t.string :zipcode
|
@@ -39,7 +36,7 @@ module ActiveRecord
|
|
39
36
|
#
|
40
37
|
# 1. Define <tt>#up</tt> and <tt>#down</tt> methods instead of <tt>#change</tt>:
|
41
38
|
#
|
42
|
-
# class ReversibleMigrationExample < ActiveRecord::Migration[
|
39
|
+
# class ReversibleMigrationExample < ActiveRecord::Migration[8.0]
|
43
40
|
# def up
|
44
41
|
# create_table :distributors do |t|
|
45
42
|
# t.string :zipcode
|
@@ -64,7 +61,7 @@ module ActiveRecord
|
|
64
61
|
#
|
65
62
|
# 2. Use the #reversible method in <tt>#change</tt> method:
|
66
63
|
#
|
67
|
-
# class ReversibleMigrationExample < ActiveRecord::Migration[
|
64
|
+
# class ReversibleMigrationExample < ActiveRecord::Migration[8.0]
|
68
65
|
# def change
|
69
66
|
# create_table :distributors do |t|
|
70
67
|
# t.string :zipcode
|
@@ -131,6 +128,22 @@ module ActiveRecord
|
|
131
128
|
end
|
132
129
|
end
|
133
130
|
|
131
|
+
class InvalidMigrationTimestampError < MigrationError # :nodoc:
|
132
|
+
def initialize(version = nil, name = nil)
|
133
|
+
if version && name
|
134
|
+
super(<<~MSG)
|
135
|
+
Invalid timestamp #{version} for migration file: #{name}.
|
136
|
+
Timestamp must be in form YYYYMMDDHHMMSS, and less than #{(Time.now.utc + 1.day).strftime("%Y%m%d%H%M%S")}.
|
137
|
+
MSG
|
138
|
+
else
|
139
|
+
super(<<~MSG)
|
140
|
+
Invalid timestamp for migration.
|
141
|
+
Timestamp must be in form YYYYMMDDHHMMSS, and less than #{(Time.now.utc + 1.day).strftime("%Y%m%d%H%M%S")}.
|
142
|
+
MSG
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
134
147
|
class PendingMigrationError < MigrationError # :nodoc:
|
135
148
|
include ActiveSupport::ActionableError
|
136
149
|
|
@@ -145,8 +158,7 @@ module ActiveRecord
|
|
145
158
|
|
146
159
|
def initialize(message = nil, pending_migrations: nil)
|
147
160
|
if pending_migrations.nil?
|
148
|
-
|
149
|
-
pending_migrations = connection.migration_context.open.pending_migrations
|
161
|
+
pending_migrations = connection_pool.migration_context.open.pending_migrations
|
150
162
|
end
|
151
163
|
|
152
164
|
super(message || detailed_migration_message(pending_migrations))
|
@@ -167,8 +179,8 @@ module ActiveRecord
|
|
167
179
|
message
|
168
180
|
end
|
169
181
|
|
170
|
-
def
|
171
|
-
ActiveRecord::Tasks::DatabaseTasks.
|
182
|
+
def connection_pool
|
183
|
+
ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
|
172
184
|
end
|
173
185
|
end
|
174
186
|
|
@@ -235,7 +247,7 @@ module ActiveRecord
|
|
235
247
|
#
|
236
248
|
# Example of a simple migration:
|
237
249
|
#
|
238
|
-
# class AddSsl < ActiveRecord::Migration[
|
250
|
+
# class AddSsl < ActiveRecord::Migration[8.0]
|
239
251
|
# def up
|
240
252
|
# add_column :accounts, :ssl_enabled, :boolean, default: true
|
241
253
|
# end
|
@@ -255,7 +267,7 @@ module ActiveRecord
|
|
255
267
|
#
|
256
268
|
# Example of a more complex migration that also needs to initialize data:
|
257
269
|
#
|
258
|
-
# class AddSystemSettings < ActiveRecord::Migration[
|
270
|
+
# class AddSystemSettings < ActiveRecord::Migration[8.0]
|
259
271
|
# def up
|
260
272
|
# create_table :system_settings do |t|
|
261
273
|
# t.string :name
|
@@ -342,7 +354,7 @@ module ActiveRecord
|
|
342
354
|
#
|
343
355
|
# === Deletion
|
344
356
|
#
|
345
|
-
# * <tt>drop_table(
|
357
|
+
# * <tt>drop_table(*names)</tt>: Drops the given tables.
|
346
358
|
# * <tt>drop_join_table(table_1, table_2, options)</tt>: Drops the join table
|
347
359
|
# specified by the given arguments.
|
348
360
|
# * <tt>remove_column(table_name, column_name, type, options)</tt>: Removes the column
|
@@ -384,7 +396,7 @@ module ActiveRecord
|
|
384
396
|
# $ bin/rails generate migration add_fieldname_to_tablename fieldname:string
|
385
397
|
#
|
386
398
|
# This will generate the file <tt>timestamp_add_fieldname_to_tablename.rb</tt>, which will look like this:
|
387
|
-
# class AddFieldnameToTablename < ActiveRecord::Migration[
|
399
|
+
# class AddFieldnameToTablename < ActiveRecord::Migration[8.0]
|
388
400
|
# def change
|
389
401
|
# add_column :tablenames, :fieldname, :string
|
390
402
|
# end
|
@@ -410,7 +422,7 @@ module ActiveRecord
|
|
410
422
|
#
|
411
423
|
# Not all migrations change the schema. Some just fix the data:
|
412
424
|
#
|
413
|
-
# class RemoveEmptyTags < ActiveRecord::Migration[
|
425
|
+
# class RemoveEmptyTags < ActiveRecord::Migration[8.0]
|
414
426
|
# def up
|
415
427
|
# Tag.all.each { |tag| tag.destroy if tag.pages.empty? }
|
416
428
|
# end
|
@@ -423,7 +435,7 @@ module ActiveRecord
|
|
423
435
|
#
|
424
436
|
# Others remove columns when they migrate up instead of down:
|
425
437
|
#
|
426
|
-
# class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[
|
438
|
+
# class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[8.0]
|
427
439
|
# def up
|
428
440
|
# remove_column :items, :incomplete_items_count
|
429
441
|
# remove_column :items, :completed_items_count
|
@@ -437,7 +449,7 @@ module ActiveRecord
|
|
437
449
|
#
|
438
450
|
# And sometimes you need to do something in SQL not abstracted directly by migrations:
|
439
451
|
#
|
440
|
-
# class MakeJoinUnique < ActiveRecord::Migration[
|
452
|
+
# class MakeJoinUnique < ActiveRecord::Migration[8.0]
|
441
453
|
# def up
|
442
454
|
# execute "ALTER TABLE `pages_linked_pages` ADD UNIQUE `page_id_linked_page_id` (`page_id`,`linked_page_id`)"
|
443
455
|
# end
|
@@ -454,7 +466,7 @@ module ActiveRecord
|
|
454
466
|
# <tt>Base#reset_column_information</tt> in order to ensure that the model has the
|
455
467
|
# latest column data from after the new column was added. Example:
|
456
468
|
#
|
457
|
-
# class AddPeopleSalary < ActiveRecord::Migration[
|
469
|
+
# class AddPeopleSalary < ActiveRecord::Migration[8.0]
|
458
470
|
# def up
|
459
471
|
# add_column :people, :salary, :integer
|
460
472
|
# Person.reset_column_information
|
@@ -470,7 +482,7 @@ module ActiveRecord
|
|
470
482
|
# them to the console as they happen, along with benchmarks describing how
|
471
483
|
# long each step took.
|
472
484
|
#
|
473
|
-
# You can quiet them down by setting ActiveRecord::Migration.verbose = false
|
485
|
+
# You can quiet them down by setting <tt>ActiveRecord::Migration.verbose = false</tt>.
|
474
486
|
#
|
475
487
|
# You can also insert your own messages and benchmarks by using the +say_with_time+
|
476
488
|
# method:
|
@@ -494,7 +506,11 @@ module ActiveRecord
|
|
494
506
|
#
|
495
507
|
# 20080717013526_your_migration_name.rb
|
496
508
|
#
|
497
|
-
# The prefix is a generation timestamp (in UTC).
|
509
|
+
# The prefix is a generation timestamp (in UTC). Timestamps should not be
|
510
|
+
# modified manually. To validate that migration timestamps adhere to the
|
511
|
+
# format Active Record expects, you can use the following configuration option:
|
512
|
+
#
|
513
|
+
# config.active_record.validate_migration_timestamps = true
|
498
514
|
#
|
499
515
|
# If you'd prefer to use numeric prefixes, you can turn timestamped migrations
|
500
516
|
# off by setting:
|
@@ -512,7 +528,7 @@ module ActiveRecord
|
|
512
528
|
# To define a reversible migration, define the +change+ method in your
|
513
529
|
# migration like this:
|
514
530
|
#
|
515
|
-
# class TenderloveMigration < ActiveRecord::Migration[
|
531
|
+
# class TenderloveMigration < ActiveRecord::Migration[8.0]
|
516
532
|
# def change
|
517
533
|
# create_table(:horses) do |t|
|
518
534
|
# t.column :content, :text
|
@@ -542,7 +558,7 @@ module ActiveRecord
|
|
542
558
|
# can't execute inside a transaction though, and for these situations
|
543
559
|
# you can turn the automatic transactions off.
|
544
560
|
#
|
545
|
-
# class ChangeEnum < ActiveRecord::Migration[
|
561
|
+
# class ChangeEnum < ActiveRecord::Migration[8.0]
|
546
562
|
# disable_ddl_transaction!
|
547
563
|
#
|
548
564
|
# def up
|
@@ -585,7 +601,7 @@ module ActiveRecord
|
|
585
601
|
end
|
586
602
|
end
|
587
603
|
|
588
|
-
def drop_table(
|
604
|
+
def drop_table(*table_names, **options)
|
589
605
|
if block_given?
|
590
606
|
super { |t| yield compatible_table_definition(t) }
|
591
607
|
else
|
@@ -662,10 +678,6 @@ module ActiveRecord
|
|
662
678
|
paths = all_configs.flat_map { |config| config.migrations_paths || Migrator.migrations_paths }.uniq
|
663
679
|
@file_watcher.new([], paths.index_with(["rb"]), &block)
|
664
680
|
end
|
665
|
-
|
666
|
-
def connection
|
667
|
-
ActiveRecord::Tasks::DatabaseTasks.migration_connection
|
668
|
-
end
|
669
681
|
end
|
670
682
|
|
671
683
|
class << self
|
@@ -676,30 +688,13 @@ module ActiveRecord
|
|
676
688
|
delegate || superclass.nearest_delegate
|
677
689
|
end
|
678
690
|
|
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
|
694
|
-
end
|
695
|
-
|
696
691
|
# Raises ActiveRecord::PendingMigrationError error if any migrations are pending
|
697
692
|
# for all database configurations in an environment.
|
698
693
|
def check_all_pending!
|
699
694
|
pending_migrations = []
|
700
695
|
|
701
|
-
ActiveRecord::Tasks::DatabaseTasks.
|
702
|
-
if pending =
|
696
|
+
ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: env) do |pool|
|
697
|
+
if pending = pool.migration_context.open.pending_migrations
|
703
698
|
pending_migrations << pending
|
704
699
|
end
|
705
700
|
end
|
@@ -713,13 +708,7 @@ module ActiveRecord
|
|
713
708
|
|
714
709
|
def load_schema_if_pending!
|
715
710
|
if any_schema_needs_update?
|
716
|
-
|
717
|
-
root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
|
718
|
-
|
719
|
-
FileUtils.cd(root) do
|
720
|
-
Base.connection_handler.clear_all_connections!(:all)
|
721
|
-
system("bin/rails db:test:prepare")
|
722
|
-
end
|
711
|
+
load_schema!
|
723
712
|
end
|
724
713
|
|
725
714
|
check_pending_migrations
|
@@ -731,10 +720,9 @@ module ActiveRecord
|
|
731
720
|
end
|
732
721
|
end
|
733
722
|
|
734
|
-
def method_missing(name,
|
735
|
-
nearest_delegate.send(name,
|
723
|
+
def method_missing(name, ...) # :nodoc:
|
724
|
+
nearest_delegate.send(name, ...)
|
736
725
|
end
|
737
|
-
ruby2_keywords(:method_missing)
|
738
726
|
|
739
727
|
def migrate(direction)
|
740
728
|
new.migrate direction
|
@@ -771,8 +759,8 @@ module ActiveRecord
|
|
771
759
|
pending_migrations = []
|
772
760
|
|
773
761
|
ActiveRecord::Base.configurations.configs_for(env_name: env).each do |db_config|
|
774
|
-
ActiveRecord::PendingMigrationConnection.
|
775
|
-
if pending =
|
762
|
+
ActiveRecord::PendingMigrationConnection.with_temporary_pool(db_config) do |pool|
|
763
|
+
if pending = pool.migration_context.open.pending_migrations
|
776
764
|
pending_migrations << pending
|
777
765
|
end
|
778
766
|
end
|
@@ -784,12 +772,28 @@ module ActiveRecord
|
|
784
772
|
def env
|
785
773
|
ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
|
786
774
|
end
|
775
|
+
|
776
|
+
def load_schema!
|
777
|
+
# Roundtrip to Rake to allow plugins to hook into database initialization.
|
778
|
+
root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
|
779
|
+
|
780
|
+
FileUtils.cd(root) do
|
781
|
+
Base.connection_handler.clear_all_connections!(:all)
|
782
|
+
system("bin/rails db:test:prepare")
|
783
|
+
end
|
784
|
+
end
|
787
785
|
end
|
788
786
|
|
789
787
|
def disable_ddl_transaction # :nodoc:
|
790
788
|
self.class.disable_ddl_transaction
|
791
789
|
end
|
792
790
|
|
791
|
+
##
|
792
|
+
# :singleton-method: verbose
|
793
|
+
#
|
794
|
+
# Specifies if migrations will write the actions they are taking to the console as they
|
795
|
+
# happen, along with benchmarks describing how long each step took. Defaults to
|
796
|
+
# true.
|
793
797
|
cattr_accessor :verbose
|
794
798
|
attr_accessor :name, :version
|
795
799
|
|
@@ -797,6 +801,7 @@ module ActiveRecord
|
|
797
801
|
@name = name
|
798
802
|
@version = version
|
799
803
|
@connection = nil
|
804
|
+
@pool = nil
|
800
805
|
end
|
801
806
|
|
802
807
|
def execution_strategy
|
@@ -814,7 +819,7 @@ module ActiveRecord
|
|
814
819
|
# and create the table 'apples' on the way up, and the reverse
|
815
820
|
# on the way down.
|
816
821
|
#
|
817
|
-
# class FixTLMigration < ActiveRecord::Migration[
|
822
|
+
# class FixTLMigration < ActiveRecord::Migration[8.0]
|
818
823
|
# def change
|
819
824
|
# revert do
|
820
825
|
# create_table(:horses) do |t|
|
@@ -833,7 +838,7 @@ module ActiveRecord
|
|
833
838
|
#
|
834
839
|
# require_relative "20121212123456_tenderlove_migration"
|
835
840
|
#
|
836
|
-
# class FixupTLMigration < ActiveRecord::Migration[
|
841
|
+
# class FixupTLMigration < ActiveRecord::Migration[8.0]
|
837
842
|
# def change
|
838
843
|
# revert TenderloveMigration
|
839
844
|
#
|
@@ -884,7 +889,7 @@ module ActiveRecord
|
|
884
889
|
# when the three columns 'first_name', 'last_name' and 'full_name' exist,
|
885
890
|
# even when migrating down:
|
886
891
|
#
|
887
|
-
# class SplitNameMigration < ActiveRecord::Migration[
|
892
|
+
# class SplitNameMigration < ActiveRecord::Migration[8.0]
|
888
893
|
# def change
|
889
894
|
# add_column :users, :first_name, :string
|
890
895
|
# add_column :users, :last_name, :string
|
@@ -912,7 +917,7 @@ module ActiveRecord
|
|
912
917
|
# In the following example, the new column +published+ will be given
|
913
918
|
# the value +true+ for all existing records.
|
914
919
|
#
|
915
|
-
# class AddPublishedToPosts < ActiveRecord::Migration[
|
920
|
+
# class AddPublishedToPosts < ActiveRecord::Migration[8.0]
|
916
921
|
# def change
|
917
922
|
# add_column :posts, :published, :boolean, default: false
|
918
923
|
# up_only do
|
@@ -964,16 +969,16 @@ module ActiveRecord
|
|
964
969
|
when :down then announce "reverting"
|
965
970
|
end
|
966
971
|
|
967
|
-
|
972
|
+
time_elapsed = nil
|
968
973
|
ActiveRecord::Tasks::DatabaseTasks.migration_connection.pool.with_connection do |conn|
|
969
|
-
|
974
|
+
time_elapsed = ActiveSupport::Benchmark.realtime do
|
970
975
|
exec_migration(conn, direction)
|
971
976
|
end
|
972
977
|
end
|
973
978
|
|
974
979
|
case direction
|
975
|
-
when :up then announce "migrated (%.4fs)" %
|
976
|
-
when :down then announce "reverted (%.4fs)" %
|
980
|
+
when :up then announce "migrated (%.4fs)" % time_elapsed; write
|
981
|
+
when :down then announce "reverted (%.4fs)" % time_elapsed; write
|
977
982
|
end
|
978
983
|
end
|
979
984
|
|
@@ -1014,8 +1019,8 @@ module ActiveRecord
|
|
1014
1019
|
def say_with_time(message)
|
1015
1020
|
say(message)
|
1016
1021
|
result = nil
|
1017
|
-
|
1018
|
-
say "%.4fs" %
|
1022
|
+
time_elapsed = ActiveSupport::Benchmark.realtime { result = yield }
|
1023
|
+
say "%.4fs" % time_elapsed, :subitem
|
1019
1024
|
say("#{result} rows", :subitem) if result.is_a?(Integer)
|
1020
1025
|
result
|
1021
1026
|
end
|
@@ -1032,6 +1037,10 @@ module ActiveRecord
|
|
1032
1037
|
@connection || ActiveRecord::Tasks::DatabaseTasks.migration_connection
|
1033
1038
|
end
|
1034
1039
|
|
1040
|
+
def connection_pool
|
1041
|
+
@pool || ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
|
1042
|
+
end
|
1043
|
+
|
1035
1044
|
def method_missing(method, *arguments, &block)
|
1036
1045
|
say_with_time "#{method}(#{format_arguments(arguments)})" do
|
1037
1046
|
unless connection.respond_to? :revert
|
@@ -1203,31 +1212,9 @@ module ActiveRecord
|
|
1203
1212
|
attr_reader :migrations_paths, :schema_migration, :internal_metadata
|
1204
1213
|
|
1205
1214
|
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
|
1227
|
-
|
1228
1215
|
@migrations_paths = migrations_paths
|
1229
|
-
@schema_migration = schema_migration || SchemaMigration.new(
|
1230
|
-
@internal_metadata = internal_metadata || InternalMetadata.new(
|
1216
|
+
@schema_migration = schema_migration || SchemaMigration.new(connection_pool)
|
1217
|
+
@internal_metadata = internal_metadata || InternalMetadata.new(connection_pool)
|
1231
1218
|
end
|
1232
1219
|
|
1233
1220
|
# Runs the migrations in the +migrations_path+.
|
@@ -1317,6 +1304,9 @@ module ActiveRecord
|
|
1317
1304
|
migrations = migration_files.map do |file|
|
1318
1305
|
version, name, scope = parse_migration_filename(file)
|
1319
1306
|
raise IllegalMigrationNameError.new(file) unless version
|
1307
|
+
if validate_timestamp? && !valid_migration_timestamp?(version)
|
1308
|
+
raise InvalidMigrationTimestampError.new(version, name)
|
1309
|
+
end
|
1320
1310
|
version = version.to_i
|
1321
1311
|
name = name.camelize
|
1322
1312
|
|
@@ -1332,6 +1322,9 @@ module ActiveRecord
|
|
1332
1322
|
file_list = migration_files.filter_map do |file|
|
1333
1323
|
version, name, scope = parse_migration_filename(file)
|
1334
1324
|
raise IllegalMigrationNameError.new(file) unless version
|
1325
|
+
if validate_timestamp? && !valid_migration_timestamp?(version)
|
1326
|
+
raise InvalidMigrationTimestampError.new(version, name)
|
1327
|
+
end
|
1335
1328
|
version = schema_migration.normalize_migration_number(version)
|
1336
1329
|
status = db_list.delete(version) ? "up" : "down"
|
1337
1330
|
[status, version, (name + scope).humanize]
|
@@ -1353,11 +1346,12 @@ module ActiveRecord
|
|
1353
1346
|
end
|
1354
1347
|
|
1355
1348
|
def last_stored_environment # :nodoc:
|
1356
|
-
|
1349
|
+
internal_metadata = connection_pool.internal_metadata
|
1350
|
+
return nil unless internal_metadata.enabled?
|
1357
1351
|
return nil if current_version == 0
|
1358
|
-
raise NoEnvironmentInSchemaError unless
|
1352
|
+
raise NoEnvironmentInSchemaError unless internal_metadata.table_exists?
|
1359
1353
|
|
1360
|
-
environment =
|
1354
|
+
environment = internal_metadata[:environment]
|
1361
1355
|
raise NoEnvironmentInSchemaError unless environment
|
1362
1356
|
environment
|
1363
1357
|
end
|
@@ -1367,6 +1361,10 @@ module ActiveRecord
|
|
1367
1361
|
ActiveRecord::Tasks::DatabaseTasks.migration_connection
|
1368
1362
|
end
|
1369
1363
|
|
1364
|
+
def connection_pool
|
1365
|
+
ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
|
1366
|
+
end
|
1367
|
+
|
1370
1368
|
def migration_files
|
1371
1369
|
paths = Array(migrations_paths)
|
1372
1370
|
Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
|
@@ -1376,6 +1374,14 @@ module ActiveRecord
|
|
1376
1374
|
File.basename(filename).scan(Migration::MigrationFilenameRegexp).first
|
1377
1375
|
end
|
1378
1376
|
|
1377
|
+
def validate_timestamp?
|
1378
|
+
ActiveRecord.timestamped_migrations && ActiveRecord.validate_migration_timestamps
|
1379
|
+
end
|
1380
|
+
|
1381
|
+
def valid_migration_timestamp?(version)
|
1382
|
+
version.to_i < (Time.now.utc + 1.day).strftime("%Y%m%d%H%M%S").to_i
|
1383
|
+
end
|
1384
|
+
|
1379
1385
|
def move(direction, steps)
|
1380
1386
|
migrator = Migrator.new(direction, migrations, schema_migration, internal_metadata)
|
1381
1387
|
|
@@ -1402,9 +1408,9 @@ module ActiveRecord
|
|
1402
1408
|
|
1403
1409
|
# For cases where a table doesn't exist like loading from schema cache
|
1404
1410
|
def current_version
|
1405
|
-
|
1406
|
-
schema_migration = SchemaMigration.new(
|
1407
|
-
internal_metadata = InternalMetadata.new(
|
1411
|
+
connection_pool = ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
|
1412
|
+
schema_migration = SchemaMigration.new(connection_pool)
|
1413
|
+
internal_metadata = InternalMetadata.new(connection_pool)
|
1408
1414
|
|
1409
1415
|
MigrationContext.new(migrations_paths, schema_migration, internal_metadata).current_version
|
1410
1416
|
end
|