activerecord 7.1.5.2 → 8.1.2.1
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 +567 -2443
- data/README.rdoc +16 -16
- data/examples/performance.rb +2 -2
- data/lib/active_record/association_relation.rb +3 -2
- 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 +31 -8
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
- data/lib/active_record/associations/builder/association.rb +23 -11
- data/lib/active_record/associations/builder/belongs_to.rb +18 -4
- data/lib/active_record/associations/builder/collection_association.rb +7 -3
- 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/builder/singular_association.rb +33 -5
- data/lib/active_record/associations/collection_association.rb +17 -9
- data/lib/active_record/associations/collection_proxy.rb +36 -5
- data/lib/active_record/associations/deprecation.rb +88 -0
- data/lib/active_record/associations/disable_joins_association_scope.rb +1 -1
- data/lib/active_record/associations/errors.rb +268 -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/join_dependency.rb +4 -2
- 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/batch.rb +7 -1
- data/lib/active_record/associations/preloader/branch.rb +8 -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 +250 -315
- 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/query.rb +34 -0
- data/lib/active_record/attribute_methods/read.rb +1 -13
- data/lib/active_record/attribute_methods/serialization.rb +20 -27
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +19 -20
- data/lib/active_record/attribute_methods.rb +71 -75
- data/lib/active_record/attributes.rb +96 -68
- data/lib/active_record/autosave_association.rb +93 -58
- data/lib/active_record/base.rb +5 -7
- data/lib/active_record/callbacks.rb +1 -1
- data/lib/active_record/coders/json.rb +14 -5
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +50 -126
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +16 -4
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +52 -13
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +681 -135
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +165 -86
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +226 -78
- data/lib/active_record/connection_adapters/abstract/quoting.rb +79 -114
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +11 -7
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +37 -36
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +136 -34
- data/lib/active_record/connection_adapters/abstract/transaction.rb +163 -68
- data/lib/active_record/connection_adapters/abstract_adapter.rb +197 -129
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +112 -63
- data/lib/active_record/connection_adapters/column.rb +17 -4
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +11 -3
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -57
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +41 -10
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +79 -46
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +97 -101
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +14 -33
- data/lib/active_record/connection_adapters/pool_config.rb +14 -13
- data/lib/active_record/connection_adapters/postgresql/column.rb +4 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +98 -44
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +3 -3
- 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/type_map_initializer.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +79 -68
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -4
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +9 -17
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +44 -41
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +69 -32
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +155 -75
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +104 -121
- data/lib/active_record/connection_adapters/schema_cache.rb +126 -133
- data/lib/active_record/connection_adapters/sqlite3/column.rb +14 -1
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +91 -95
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +57 -54
- 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 +43 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +38 -15
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +231 -111
- data/lib/active_record/connection_adapters/statement_pool.rb +4 -2
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +40 -69
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +19 -65
- data/lib/active_record/connection_adapters.rb +66 -0
- data/lib/active_record/connection_handling.rb +88 -46
- data/lib/active_record/core.rb +142 -58
- data/lib/active_record/counter_cache.rb +52 -18
- data/lib/active_record/database_configurations/connection_url_resolver.rb +9 -2
- data/lib/active_record/database_configurations/database_config.rb +28 -5
- data/lib/active_record/database_configurations/hash_config.rb +103 -41
- data/lib/active_record/database_configurations/url_config.rb +30 -1
- data/lib/active_record/database_configurations.rb +8 -4
- data/lib/active_record/delegated_type.rb +43 -19
- data/lib/active_record/dynamic_matchers.rb +56 -71
- data/lib/active_record/encryption/config.rb +3 -1
- data/lib/active_record/encryption/encryptable_record.rb +12 -12
- data/lib/active_record/encryption/encrypted_attribute_type.rb +35 -6
- data/lib/active_record/encryption/encryptor.rb +58 -22
- 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 +9 -2
- data/lib/active_record/enum.rb +57 -36
- data/lib/active_record/errors.rb +76 -26
- data/lib/active_record/explain.rb +14 -25
- data/lib/active_record/explain_registry.rb +51 -2
- data/lib/active_record/filter_attribute_handler.rb +73 -0
- data/lib/active_record/fixture_set/table_row.rb +19 -2
- data/lib/active_record/fixtures.rb +39 -35
- data/lib/active_record/future_result.rb +21 -13
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +5 -3
- data/lib/active_record/insert_all.rb +28 -20
- data/lib/active_record/integration.rb +4 -1
- data/lib/active_record/internal_metadata.rb +48 -34
- data/lib/active_record/locking/optimistic.rb +15 -7
- data/lib/active_record/locking/pessimistic.rb +5 -0
- data/lib/active_record/log_subscriber.rb +3 -34
- data/lib/active_record/message_pack.rb +1 -1
- data/lib/active_record/middleware/shard_selector.rb +34 -17
- data/lib/active_record/migration/command_recorder.rb +46 -14
- data/lib/active_record/migration/compatibility.rb +40 -25
- data/lib/active_record/migration/default_schema_versions_formatter.rb +30 -0
- 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 +119 -103
- data/lib/active_record/model_schema.rb +66 -78
- data/lib/active_record/nested_attributes.rb +17 -9
- data/lib/active_record/persistence.rb +161 -454
- data/lib/active_record/query_cache.rb +33 -15
- data/lib/active_record/query_logs.rb +106 -39
- data/lib/active_record/query_logs_formatter.rb +17 -28
- data/lib/active_record/querying.rb +28 -16
- data/lib/active_record/railtie.rb +61 -74
- data/lib/active_record/railties/controller_runtime.rb +19 -5
- data/lib/active_record/railties/databases.rake +64 -78
- data/lib/active_record/railties/job_checkpoints.rb +15 -0
- data/lib/active_record/railties/job_runtime.rb +10 -11
- data/lib/active_record/reflection.rb +147 -53
- data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
- data/lib/active_record/relation/batches.rb +153 -73
- data/lib/active_record/relation/calculations.rb +146 -96
- data/lib/active_record/relation/delegation.rb +30 -23
- data/lib/active_record/relation/finder_methods.rb +64 -34
- 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 +19 -11
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +8 -8
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +4 -3
- data/lib/active_record/relation/predicate_builder.rb +25 -10
- data/lib/active_record/relation/query_attribute.rb +4 -2
- data/lib/active_record/relation/query_methods.rb +351 -124
- data/lib/active_record/relation/spawn_methods.rb +9 -25
- data/lib/active_record/relation/where_clause.rb +17 -30
- data/lib/active_record/relation.rb +590 -124
- data/lib/active_record/result.rb +131 -59
- data/lib/active_record/runtime_registry.rb +44 -21
- data/lib/active_record/sanitization.rb +33 -25
- data/lib/active_record/schema.rb +8 -6
- data/lib/active_record/schema_dumper.rb +66 -31
- data/lib/active_record/schema_migration.rb +31 -14
- data/lib/active_record/scoping/named.rb +6 -2
- data/lib/active_record/scoping.rb +0 -1
- data/lib/active_record/secure_token.rb +3 -3
- data/lib/active_record/signed_id.rb +68 -20
- data/lib/active_record/statement_cache.rb +29 -25
- data/lib/active_record/store.rb +51 -22
- data/lib/active_record/structured_event_subscriber.rb +85 -0
- data/lib/active_record/table_metadata.rb +7 -33
- data/lib/active_record/tasks/abstract_tasks.rb +76 -0
- data/lib/active_record/tasks/database_tasks.rb +118 -90
- data/lib/active_record/tasks/mysql_database_tasks.rb +3 -42
- data/lib/active_record/tasks/postgresql_database_tasks.rb +14 -40
- data/lib/active_record/tasks/sqlite_database_tasks.rb +17 -28
- data/lib/active_record/test_databases.rb +14 -4
- data/lib/active_record/test_fixtures.rb +123 -89
- data/lib/active_record/testing/query_assertions.rb +127 -0
- data/lib/active_record/timestamp.rb +6 -4
- data/lib/active_record/token_for.rb +22 -12
- data/lib/active_record/touch_later.rb +1 -1
- data/lib/active_record/transaction.rb +129 -0
- data/lib/active_record/transactions.rb +97 -18
- data/lib/active_record/translation.rb +0 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +2 -1
- data/lib/active_record/type/internal/timezone.rb +7 -0
- data/lib/active_record/type/json.rb +15 -2
- data/lib/active_record/type/serialized.rb +12 -7
- data/lib/active_record/type/type_map.rb +1 -1
- data/lib/active_record/type_caster/connection.rb +5 -4
- data/lib/active_record/validations/associated.rb +10 -4
- data/lib/active_record/validations/uniqueness.rb +23 -18
- data/lib/active_record/validations.rb +4 -1
- data/lib/active_record.rb +203 -59
- data/lib/arel/alias_predication.rb +3 -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/crud.rb +8 -11
- data/lib/arel/delete_manager.rb +5 -0
- data/lib/arel/nodes/binary.rb +1 -7
- data/lib/arel/nodes/bound_sql_literal.rb +9 -5
- data/lib/arel/nodes/count.rb +2 -2
- data/lib/arel/nodes/delete_statement.rb +4 -2
- data/lib/arel/nodes/function.rb +4 -10
- data/lib/arel/nodes/named_function.rb +2 -2
- data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
- data/lib/arel/nodes/node.rb +6 -5
- data/lib/arel/nodes/sql_literal.rb +8 -1
- data/lib/arel/nodes/update_statement.rb +4 -2
- data/lib/arel/nodes.rb +2 -4
- data/lib/arel/predications.rb +1 -1
- data/lib/arel/select_manager.rb +14 -5
- data/lib/arel/table.rb +3 -7
- data/lib/arel/tree_manager.rb +3 -2
- data/lib/arel/update_manager.rb +7 -1
- data/lib/arel/visitors/dot.rb +3 -3
- data/lib/arel/visitors/mysql.rb +9 -4
- data/lib/arel/visitors/postgresql.rb +56 -12
- data/lib/arel/visitors/sqlite.rb +80 -8
- data/lib/arel/visitors/to_sql.rb +34 -37
- data/lib/arel.rb +10 -4
- data/lib/rails/generators/active_record/application_record/USAGE +1 -1
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
- metadata +23 -14
- data/lib/active_record/explain_subscriber.rb +0 -34
- data/lib/active_record/normalization.rb +0 -167
- 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.1]
|
|
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.1]
|
|
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.1]
|
|
68
65
|
# def change
|
|
69
66
|
# create_table :distributors do |t|
|
|
70
67
|
# t.string :zipcode
|
|
@@ -131,22 +128,36 @@ 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
|
|
|
137
150
|
action "Run pending migrations" do
|
|
138
|
-
ActiveRecord::Tasks::DatabaseTasks.
|
|
151
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate_all
|
|
139
152
|
|
|
140
153
|
if ActiveRecord.dump_schema_after_migration
|
|
141
|
-
|
|
142
|
-
ActiveRecord::Tasks::DatabaseTasks.dump_schema(connection.pool.db_config)
|
|
154
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_all
|
|
143
155
|
end
|
|
144
156
|
end
|
|
145
157
|
|
|
146
158
|
def initialize(message = nil, pending_migrations: nil)
|
|
147
159
|
if pending_migrations.nil?
|
|
148
|
-
|
|
149
|
-
pending_migrations = connection.migration_context.open.pending_migrations
|
|
160
|
+
pending_migrations = connection_pool.migration_context.open.pending_migrations
|
|
150
161
|
end
|
|
151
162
|
|
|
152
163
|
super(message || detailed_migration_message(pending_migrations))
|
|
@@ -167,8 +178,8 @@ module ActiveRecord
|
|
|
167
178
|
message
|
|
168
179
|
end
|
|
169
180
|
|
|
170
|
-
def
|
|
171
|
-
ActiveRecord::Tasks::DatabaseTasks.
|
|
181
|
+
def connection_pool
|
|
182
|
+
ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
|
|
172
183
|
end
|
|
173
184
|
end
|
|
174
185
|
|
|
@@ -235,7 +246,7 @@ module ActiveRecord
|
|
|
235
246
|
#
|
|
236
247
|
# Example of a simple migration:
|
|
237
248
|
#
|
|
238
|
-
# class AddSsl < ActiveRecord::Migration[
|
|
249
|
+
# class AddSsl < ActiveRecord::Migration[8.1]
|
|
239
250
|
# def up
|
|
240
251
|
# add_column :accounts, :ssl_enabled, :boolean, default: true
|
|
241
252
|
# end
|
|
@@ -255,7 +266,7 @@ module ActiveRecord
|
|
|
255
266
|
#
|
|
256
267
|
# Example of a more complex migration that also needs to initialize data:
|
|
257
268
|
#
|
|
258
|
-
# class AddSystemSettings < ActiveRecord::Migration[
|
|
269
|
+
# class AddSystemSettings < ActiveRecord::Migration[8.1]
|
|
259
270
|
# def up
|
|
260
271
|
# create_table :system_settings do |t|
|
|
261
272
|
# t.string :name
|
|
@@ -342,7 +353,7 @@ module ActiveRecord
|
|
|
342
353
|
#
|
|
343
354
|
# === Deletion
|
|
344
355
|
#
|
|
345
|
-
# * <tt>drop_table(
|
|
356
|
+
# * <tt>drop_table(*names)</tt>: Drops the given tables.
|
|
346
357
|
# * <tt>drop_join_table(table_1, table_2, options)</tt>: Drops the join table
|
|
347
358
|
# specified by the given arguments.
|
|
348
359
|
# * <tt>remove_column(table_name, column_name, type, options)</tt>: Removes the column
|
|
@@ -384,7 +395,7 @@ module ActiveRecord
|
|
|
384
395
|
# $ bin/rails generate migration add_fieldname_to_tablename fieldname:string
|
|
385
396
|
#
|
|
386
397
|
# This will generate the file <tt>timestamp_add_fieldname_to_tablename.rb</tt>, which will look like this:
|
|
387
|
-
# class AddFieldnameToTablename < ActiveRecord::Migration[
|
|
398
|
+
# class AddFieldnameToTablename < ActiveRecord::Migration[8.1]
|
|
388
399
|
# def change
|
|
389
400
|
# add_column :tablenames, :fieldname, :string
|
|
390
401
|
# end
|
|
@@ -410,7 +421,7 @@ module ActiveRecord
|
|
|
410
421
|
#
|
|
411
422
|
# Not all migrations change the schema. Some just fix the data:
|
|
412
423
|
#
|
|
413
|
-
# class RemoveEmptyTags < ActiveRecord::Migration[
|
|
424
|
+
# class RemoveEmptyTags < ActiveRecord::Migration[8.1]
|
|
414
425
|
# def up
|
|
415
426
|
# Tag.all.each { |tag| tag.destroy if tag.pages.empty? }
|
|
416
427
|
# end
|
|
@@ -423,7 +434,7 @@ module ActiveRecord
|
|
|
423
434
|
#
|
|
424
435
|
# Others remove columns when they migrate up instead of down:
|
|
425
436
|
#
|
|
426
|
-
# class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[
|
|
437
|
+
# class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[8.1]
|
|
427
438
|
# def up
|
|
428
439
|
# remove_column :items, :incomplete_items_count
|
|
429
440
|
# remove_column :items, :completed_items_count
|
|
@@ -437,7 +448,7 @@ module ActiveRecord
|
|
|
437
448
|
#
|
|
438
449
|
# And sometimes you need to do something in SQL not abstracted directly by migrations:
|
|
439
450
|
#
|
|
440
|
-
# class MakeJoinUnique < ActiveRecord::Migration[
|
|
451
|
+
# class MakeJoinUnique < ActiveRecord::Migration[8.1]
|
|
441
452
|
# def up
|
|
442
453
|
# execute "ALTER TABLE `pages_linked_pages` ADD UNIQUE `page_id_linked_page_id` (`page_id`,`linked_page_id`)"
|
|
443
454
|
# end
|
|
@@ -454,7 +465,7 @@ module ActiveRecord
|
|
|
454
465
|
# <tt>Base#reset_column_information</tt> in order to ensure that the model has the
|
|
455
466
|
# latest column data from after the new column was added. Example:
|
|
456
467
|
#
|
|
457
|
-
# class AddPeopleSalary < ActiveRecord::Migration[
|
|
468
|
+
# class AddPeopleSalary < ActiveRecord::Migration[8.1]
|
|
458
469
|
# def up
|
|
459
470
|
# add_column :people, :salary, :integer
|
|
460
471
|
# Person.reset_column_information
|
|
@@ -470,7 +481,7 @@ module ActiveRecord
|
|
|
470
481
|
# them to the console as they happen, along with benchmarks describing how
|
|
471
482
|
# long each step took.
|
|
472
483
|
#
|
|
473
|
-
# You can quiet them down by setting ActiveRecord::Migration.verbose = false
|
|
484
|
+
# You can quiet them down by setting <tt>ActiveRecord::Migration.verbose = false</tt>.
|
|
474
485
|
#
|
|
475
486
|
# You can also insert your own messages and benchmarks by using the +say_with_time+
|
|
476
487
|
# method:
|
|
@@ -494,7 +505,11 @@ module ActiveRecord
|
|
|
494
505
|
#
|
|
495
506
|
# 20080717013526_your_migration_name.rb
|
|
496
507
|
#
|
|
497
|
-
# The prefix is a generation timestamp (in UTC).
|
|
508
|
+
# The prefix is a generation timestamp (in UTC). Timestamps should not be
|
|
509
|
+
# modified manually. To validate that migration timestamps adhere to the
|
|
510
|
+
# format Active Record expects, you can use the following configuration option:
|
|
511
|
+
#
|
|
512
|
+
# config.active_record.validate_migration_timestamps = true
|
|
498
513
|
#
|
|
499
514
|
# If you'd prefer to use numeric prefixes, you can turn timestamped migrations
|
|
500
515
|
# off by setting:
|
|
@@ -512,7 +527,7 @@ module ActiveRecord
|
|
|
512
527
|
# To define a reversible migration, define the +change+ method in your
|
|
513
528
|
# migration like this:
|
|
514
529
|
#
|
|
515
|
-
# class TenderloveMigration < ActiveRecord::Migration[
|
|
530
|
+
# class TenderloveMigration < ActiveRecord::Migration[8.1]
|
|
516
531
|
# def change
|
|
517
532
|
# create_table(:horses) do |t|
|
|
518
533
|
# t.column :content, :text
|
|
@@ -542,7 +557,7 @@ module ActiveRecord
|
|
|
542
557
|
# can't execute inside a transaction though, and for these situations
|
|
543
558
|
# you can turn the automatic transactions off.
|
|
544
559
|
#
|
|
545
|
-
# class ChangeEnum < ActiveRecord::Migration[
|
|
560
|
+
# class ChangeEnum < ActiveRecord::Migration[8.1]
|
|
546
561
|
# disable_ddl_transaction!
|
|
547
562
|
#
|
|
548
563
|
# def up
|
|
@@ -555,6 +570,7 @@ module ActiveRecord
|
|
|
555
570
|
class Migration
|
|
556
571
|
autoload :CommandRecorder, "active_record/migration/command_recorder"
|
|
557
572
|
autoload :Compatibility, "active_record/migration/compatibility"
|
|
573
|
+
autoload :DefaultSchemaVersionsFormatter, "active_record/migration/default_schema_versions_formatter"
|
|
558
574
|
autoload :JoinTable, "active_record/migration/join_table"
|
|
559
575
|
autoload :ExecutionStrategy, "active_record/migration/execution_strategy"
|
|
560
576
|
autoload :DefaultStrategy, "active_record/migration/default_strategy"
|
|
@@ -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
|
|
@@ -759,7 +747,7 @@ module ActiveRecord
|
|
|
759
747
|
private
|
|
760
748
|
def any_schema_needs_update?
|
|
761
749
|
!db_configs_in_current_env.all? do |db_config|
|
|
762
|
-
Tasks::DatabaseTasks.schema_up_to_date?(db_config
|
|
750
|
+
Tasks::DatabaseTasks.schema_up_to_date?(db_config)
|
|
763
751
|
end
|
|
764
752
|
end
|
|
765
753
|
|
|
@@ -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,33 @@ 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
|
|
785
|
+
|
|
786
|
+
def respond_to_missing?(method, include_private = false)
|
|
787
|
+
return false if nearest_delegate == delegate
|
|
788
|
+
nearest_delegate.respond_to?(method, include_private)
|
|
789
|
+
end
|
|
787
790
|
end
|
|
788
791
|
|
|
789
792
|
def disable_ddl_transaction # :nodoc:
|
|
790
793
|
self.class.disable_ddl_transaction
|
|
791
794
|
end
|
|
792
795
|
|
|
796
|
+
##
|
|
797
|
+
# :singleton-method: verbose
|
|
798
|
+
#
|
|
799
|
+
# Specifies if migrations will write the actions they are taking to the console as they
|
|
800
|
+
# happen, along with benchmarks describing how long each step took. Defaults to
|
|
801
|
+
# true.
|
|
793
802
|
cattr_accessor :verbose
|
|
794
803
|
attr_accessor :name, :version
|
|
795
804
|
|
|
@@ -797,6 +806,7 @@ module ActiveRecord
|
|
|
797
806
|
@name = name
|
|
798
807
|
@version = version
|
|
799
808
|
@connection = nil
|
|
809
|
+
@pool = nil
|
|
800
810
|
end
|
|
801
811
|
|
|
802
812
|
def execution_strategy
|
|
@@ -814,7 +824,7 @@ module ActiveRecord
|
|
|
814
824
|
# and create the table 'apples' on the way up, and the reverse
|
|
815
825
|
# on the way down.
|
|
816
826
|
#
|
|
817
|
-
# class FixTLMigration < ActiveRecord::Migration[
|
|
827
|
+
# class FixTLMigration < ActiveRecord::Migration[8.1]
|
|
818
828
|
# def change
|
|
819
829
|
# revert do
|
|
820
830
|
# create_table(:horses) do |t|
|
|
@@ -833,7 +843,7 @@ module ActiveRecord
|
|
|
833
843
|
#
|
|
834
844
|
# require_relative "20121212123456_tenderlove_migration"
|
|
835
845
|
#
|
|
836
|
-
# class FixupTLMigration < ActiveRecord::Migration[
|
|
846
|
+
# class FixupTLMigration < ActiveRecord::Migration[8.1]
|
|
837
847
|
# def change
|
|
838
848
|
# revert TenderloveMigration
|
|
839
849
|
#
|
|
@@ -884,7 +894,7 @@ module ActiveRecord
|
|
|
884
894
|
# when the three columns 'first_name', 'last_name' and 'full_name' exist,
|
|
885
895
|
# even when migrating down:
|
|
886
896
|
#
|
|
887
|
-
# class SplitNameMigration < ActiveRecord::Migration[
|
|
897
|
+
# class SplitNameMigration < ActiveRecord::Migration[8.1]
|
|
888
898
|
# def change
|
|
889
899
|
# add_column :users, :first_name, :string
|
|
890
900
|
# add_column :users, :last_name, :string
|
|
@@ -912,7 +922,7 @@ module ActiveRecord
|
|
|
912
922
|
# In the following example, the new column +published+ will be given
|
|
913
923
|
# the value +true+ for all existing records.
|
|
914
924
|
#
|
|
915
|
-
# class AddPublishedToPosts < ActiveRecord::Migration[
|
|
925
|
+
# class AddPublishedToPosts < ActiveRecord::Migration[8.1]
|
|
916
926
|
# def change
|
|
917
927
|
# add_column :posts, :published, :boolean, default: false
|
|
918
928
|
# up_only do
|
|
@@ -964,16 +974,16 @@ module ActiveRecord
|
|
|
964
974
|
when :down then announce "reverting"
|
|
965
975
|
end
|
|
966
976
|
|
|
967
|
-
|
|
977
|
+
time_elapsed = nil
|
|
968
978
|
ActiveRecord::Tasks::DatabaseTasks.migration_connection.pool.with_connection do |conn|
|
|
969
|
-
|
|
979
|
+
time_elapsed = ActiveSupport::Benchmark.realtime do
|
|
970
980
|
exec_migration(conn, direction)
|
|
971
981
|
end
|
|
972
982
|
end
|
|
973
983
|
|
|
974
984
|
case direction
|
|
975
|
-
when :up then announce "migrated (%.4fs)" %
|
|
976
|
-
when :down then announce "reverted (%.4fs)" %
|
|
985
|
+
when :up then announce "migrated (%.4fs)" % time_elapsed; write
|
|
986
|
+
when :down then announce "reverted (%.4fs)" % time_elapsed; write
|
|
977
987
|
end
|
|
978
988
|
end
|
|
979
989
|
|
|
@@ -1014,8 +1024,8 @@ module ActiveRecord
|
|
|
1014
1024
|
def say_with_time(message)
|
|
1015
1025
|
say(message)
|
|
1016
1026
|
result = nil
|
|
1017
|
-
|
|
1018
|
-
say "%.4fs" %
|
|
1027
|
+
time_elapsed = ActiveSupport::Benchmark.realtime { result = yield }
|
|
1028
|
+
say "%.4fs" % time_elapsed, :subitem
|
|
1019
1029
|
say("#{result} rows", :subitem) if result.is_a?(Integer)
|
|
1020
1030
|
result
|
|
1021
1031
|
end
|
|
@@ -1032,6 +1042,10 @@ module ActiveRecord
|
|
|
1032
1042
|
@connection || ActiveRecord::Tasks::DatabaseTasks.migration_connection
|
|
1033
1043
|
end
|
|
1034
1044
|
|
|
1045
|
+
def connection_pool
|
|
1046
|
+
@pool || ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
|
|
1047
|
+
end
|
|
1048
|
+
|
|
1035
1049
|
def method_missing(method, *arguments, &block)
|
|
1036
1050
|
say_with_time "#{method}(#{format_arguments(arguments)})" do
|
|
1037
1051
|
unless connection.respond_to? :revert
|
|
@@ -1161,6 +1175,10 @@ module ActiveRecord
|
|
|
1161
1175
|
def command_recorder
|
|
1162
1176
|
CommandRecorder.new(connection)
|
|
1163
1177
|
end
|
|
1178
|
+
|
|
1179
|
+
def respond_to_missing?(method, include_private = false)
|
|
1180
|
+
execution_strategy.respond_to?(method, include_private) || super
|
|
1181
|
+
end
|
|
1164
1182
|
end
|
|
1165
1183
|
|
|
1166
1184
|
# MigrationProxy is used to defer loading of the actual migration classes
|
|
@@ -1203,31 +1221,9 @@ module ActiveRecord
|
|
|
1203
1221
|
attr_reader :migrations_paths, :schema_migration, :internal_metadata
|
|
1204
1222
|
|
|
1205
1223
|
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
1224
|
@migrations_paths = migrations_paths
|
|
1229
|
-
@schema_migration = schema_migration || SchemaMigration.new(
|
|
1230
|
-
@internal_metadata = internal_metadata || InternalMetadata.new(
|
|
1225
|
+
@schema_migration = schema_migration || SchemaMigration.new(connection_pool)
|
|
1226
|
+
@internal_metadata = internal_metadata || InternalMetadata.new(connection_pool)
|
|
1231
1227
|
end
|
|
1232
1228
|
|
|
1233
1229
|
# Runs the migrations in the +migrations_path+.
|
|
@@ -1317,6 +1313,9 @@ module ActiveRecord
|
|
|
1317
1313
|
migrations = migration_files.map do |file|
|
|
1318
1314
|
version, name, scope = parse_migration_filename(file)
|
|
1319
1315
|
raise IllegalMigrationNameError.new(file) unless version
|
|
1316
|
+
if validate_timestamp? && !valid_migration_timestamp?(version)
|
|
1317
|
+
raise InvalidMigrationTimestampError.new(version, name)
|
|
1318
|
+
end
|
|
1320
1319
|
version = version.to_i
|
|
1321
1320
|
name = name.camelize
|
|
1322
1321
|
|
|
@@ -1332,6 +1331,9 @@ module ActiveRecord
|
|
|
1332
1331
|
file_list = migration_files.filter_map do |file|
|
|
1333
1332
|
version, name, scope = parse_migration_filename(file)
|
|
1334
1333
|
raise IllegalMigrationNameError.new(file) unless version
|
|
1334
|
+
if validate_timestamp? && !valid_migration_timestamp?(version)
|
|
1335
|
+
raise InvalidMigrationTimestampError.new(version, name)
|
|
1336
|
+
end
|
|
1335
1337
|
version = schema_migration.normalize_migration_number(version)
|
|
1336
1338
|
status = db_list.delete(version) ? "up" : "down"
|
|
1337
1339
|
[status, version, (name + scope).humanize]
|
|
@@ -1353,11 +1355,12 @@ module ActiveRecord
|
|
|
1353
1355
|
end
|
|
1354
1356
|
|
|
1355
1357
|
def last_stored_environment # :nodoc:
|
|
1356
|
-
|
|
1358
|
+
internal_metadata = connection_pool.internal_metadata
|
|
1359
|
+
return nil unless internal_metadata.enabled?
|
|
1357
1360
|
return nil if current_version == 0
|
|
1358
|
-
raise NoEnvironmentInSchemaError unless
|
|
1361
|
+
raise NoEnvironmentInSchemaError unless internal_metadata.table_exists?
|
|
1359
1362
|
|
|
1360
|
-
environment =
|
|
1363
|
+
environment = internal_metadata[:environment]
|
|
1361
1364
|
raise NoEnvironmentInSchemaError unless environment
|
|
1362
1365
|
environment
|
|
1363
1366
|
end
|
|
@@ -1367,6 +1370,10 @@ module ActiveRecord
|
|
|
1367
1370
|
ActiveRecord::Tasks::DatabaseTasks.migration_connection
|
|
1368
1371
|
end
|
|
1369
1372
|
|
|
1373
|
+
def connection_pool
|
|
1374
|
+
ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
|
|
1375
|
+
end
|
|
1376
|
+
|
|
1370
1377
|
def migration_files
|
|
1371
1378
|
paths = Array(migrations_paths)
|
|
1372
1379
|
Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
|
|
@@ -1376,6 +1383,14 @@ module ActiveRecord
|
|
|
1376
1383
|
File.basename(filename).scan(Migration::MigrationFilenameRegexp).first
|
|
1377
1384
|
end
|
|
1378
1385
|
|
|
1386
|
+
def validate_timestamp?
|
|
1387
|
+
ActiveRecord.timestamped_migrations && ActiveRecord.validate_migration_timestamps
|
|
1388
|
+
end
|
|
1389
|
+
|
|
1390
|
+
def valid_migration_timestamp?(version)
|
|
1391
|
+
version.to_i < (Time.now.utc + 1.day).strftime("%Y%m%d%H%M%S").to_i
|
|
1392
|
+
end
|
|
1393
|
+
|
|
1379
1394
|
def move(direction, steps)
|
|
1380
1395
|
migrator = Migrator.new(direction, migrations, schema_migration, internal_metadata)
|
|
1381
1396
|
|
|
@@ -1402,9 +1417,9 @@ module ActiveRecord
|
|
|
1402
1417
|
|
|
1403
1418
|
# For cases where a table doesn't exist like loading from schema cache
|
|
1404
1419
|
def current_version
|
|
1405
|
-
|
|
1406
|
-
schema_migration = SchemaMigration.new(
|
|
1407
|
-
internal_metadata = InternalMetadata.new(
|
|
1420
|
+
connection_pool = ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
|
|
1421
|
+
schema_migration = SchemaMigration.new(connection_pool)
|
|
1422
|
+
internal_metadata = InternalMetadata.new(connection_pool)
|
|
1408
1423
|
|
|
1409
1424
|
MigrationContext.new(migrations_paths, schema_migration, internal_metadata).current_version
|
|
1410
1425
|
end
|
|
@@ -1523,7 +1538,8 @@ module ActiveRecord
|
|
|
1523
1538
|
return if down? && !migrated.include?(migration.version.to_i)
|
|
1524
1539
|
return if up? && migrated.include?(migration.version.to_i)
|
|
1525
1540
|
|
|
1526
|
-
|
|
1541
|
+
message = up? ? "Migrating to" : "Reverting"
|
|
1542
|
+
Base.logger.info "#{message} #{migration.name} (#{migration.version})" if Base.logger
|
|
1527
1543
|
|
|
1528
1544
|
ddl_transaction(migration) do
|
|
1529
1545
|
migration.migrate(@direction)
|