activerecord 7.1.3.4 → 7.2.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 +652 -2032
- data/README.rdoc +15 -15
- data/examples/performance.rb +2 -2
- data/lib/active_record/association_relation.rb +1 -1
- data/lib/active_record/associations/alias_tracker.rb +25 -19
- data/lib/active_record/associations/association.rb +15 -8
- data/lib/active_record/associations/belongs_to_association.rb +18 -11
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
- 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 +11 -5
- data/lib/active_record/associations/collection_proxy.rb +14 -1
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations/has_many_association.rb +3 -3
- data/lib/active_record/associations/has_many_through_association.rb +7 -1
- data/lib/active_record/associations/has_one_association.rb +2 -2
- data/lib/active_record/associations/join_dependency/join_association.rb +30 -27
- data/lib/active_record/associations/join_dependency.rb +10 -12
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +2 -1
- 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 +6 -0
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +62 -289
- 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/dirty.rb +2 -2
- data/lib/active_record/attribute_methods/primary_key.rb +23 -55
- data/lib/active_record/attribute_methods/read.rb +4 -16
- data/lib/active_record/attribute_methods/serialization.rb +4 -24
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +11 -6
- data/lib/active_record/attribute_methods/write.rb +3 -3
- data/lib/active_record/attribute_methods.rb +89 -58
- data/lib/active_record/attributes.rb +61 -47
- data/lib/active_record/autosave_association.rb +17 -31
- 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 +24 -107
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +1 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +270 -58
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +35 -18
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +190 -75
- data/lib/active_record/connection_adapters/abstract/quoting.rb +65 -91
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +23 -10
- data/lib/active_record/connection_adapters/abstract/transaction.rb +125 -62
- data/lib/active_record/connection_adapters/abstract_adapter.rb +38 -59
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +73 -19
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +9 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +43 -48
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +8 -1
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +16 -15
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +20 -32
- data/lib/active_record/connection_adapters/pool_config.rb +7 -6
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +27 -4
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
- 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/schema_definitions.rb +20 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +18 -12
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +29 -24
- data/lib/active_record/connection_adapters/schema_cache.rb +123 -128
- data/lib/active_record/connection_adapters/sqlite3/column.rb +14 -1
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +10 -6
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +44 -46
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +13 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +25 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +127 -77
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +15 -15
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +32 -65
- data/lib/active_record/connection_adapters.rb +121 -0
- data/lib/active_record/connection_handling.rb +56 -41
- data/lib/active_record/core.rb +93 -40
- data/lib/active_record/counter_cache.rb +23 -10
- data/lib/active_record/database_configurations/connection_url_resolver.rb +8 -3
- data/lib/active_record/database_configurations/database_config.rb +19 -4
- data/lib/active_record/database_configurations/hash_config.rb +44 -36
- 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 +30 -6
- data/lib/active_record/destroy_association_async_job.rb +1 -1
- data/lib/active_record/dynamic_matchers.rb +2 -2
- data/lib/active_record/encryption/encryptable_record.rb +3 -3
- data/lib/active_record/encryption/encrypted_attribute_type.rb +26 -6
- data/lib/active_record/encryption/encryptor.rb +18 -3
- 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 -4
- data/lib/active_record/encryption.rb +2 -0
- data/lib/active_record/enum.rb +19 -2
- data/lib/active_record/errors.rb +46 -20
- data/lib/active_record/explain.rb +13 -24
- data/lib/active_record/fixtures.rb +37 -31
- data/lib/active_record/future_result.rb +17 -4
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +4 -2
- data/lib/active_record/insert_all.rb +18 -15
- 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 +0 -21
- data/lib/active_record/marshalling.rb +4 -1
- data/lib/active_record/message_pack.rb +2 -2
- data/lib/active_record/migration/command_recorder.rb +2 -3
- data/lib/active_record/migration/compatibility.rb +11 -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 +85 -76
- data/lib/active_record/model_schema.rb +38 -70
- data/lib/active_record/nested_attributes.rb +24 -5
- data/lib/active_record/normalization.rb +3 -7
- data/lib/active_record/persistence.rb +32 -354
- data/lib/active_record/query_cache.rb +19 -8
- data/lib/active_record/query_logs.rb +15 -0
- data/lib/active_record/query_logs_formatter.rb +1 -1
- data/lib/active_record/querying.rb +21 -9
- data/lib/active_record/railtie.rb +50 -68
- data/lib/active_record/railties/controller_runtime.rb +13 -4
- data/lib/active_record/railties/databases.rake +42 -45
- data/lib/active_record/reflection.rb +106 -38
- data/lib/active_record/relation/batches/batch_enumerator.rb +15 -2
- data/lib/active_record/relation/batches.rb +14 -8
- data/lib/active_record/relation/calculations.rb +96 -63
- data/lib/active_record/relation/delegation.rb +8 -11
- data/lib/active_record/relation/finder_methods.rb +16 -2
- data/lib/active_record/relation/merger.rb +4 -6
- data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +9 -3
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +6 -1
- data/lib/active_record/relation/predicate_builder.rb +3 -3
- data/lib/active_record/relation/query_methods.rb +245 -65
- data/lib/active_record/relation/record_fetch_warning.rb +3 -0
- data/lib/active_record/relation/spawn_methods.rb +2 -18
- data/lib/active_record/relation/where_clause.rb +7 -19
- data/lib/active_record/relation.rb +500 -66
- data/lib/active_record/result.rb +32 -45
- data/lib/active_record/runtime_registry.rb +39 -0
- data/lib/active_record/sanitization.rb +24 -19
- data/lib/active_record/schema.rb +8 -6
- data/lib/active_record/schema_dumper.rb +19 -9
- data/lib/active_record/schema_migration.rb +30 -14
- data/lib/active_record/scoping/named.rb +1 -0
- data/lib/active_record/signed_id.rb +20 -1
- data/lib/active_record/statement_cache.rb +7 -7
- data/lib/active_record/table_metadata.rb +1 -10
- data/lib/active_record/tasks/database_tasks.rb +98 -48
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -1
- data/lib/active_record/test_fixtures.rb +87 -89
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +5 -3
- 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 +70 -14
- 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 +15 -10
- data/lib/active_record/validations.rb +4 -1
- data/lib/active_record.rb +150 -41
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/collectors/bind.rb +2 -0
- data/lib/arel/collectors/composite.rb +7 -0
- data/lib/arel/collectors/sql_string.rb +1 -1
- data/lib/arel/collectors/substitute_binds.rb +1 -1
- data/lib/arel/nodes/binary.rb +0 -6
- 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 +4 -3
- data/lib/arel/nodes/sql_literal.rb +7 -0
- 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/tree_manager.rb +8 -3
- 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 +31 -17
- data/lib/arel.rb +7 -3
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
- metadata +21 -15
@@ -7,8 +7,17 @@ module ActiveRecord
|
|
7
7
|
attr_reader :model, :connection, :inserts, :keys
|
8
8
|
attr_reader :on_duplicate, :update_only, :returning, :unique_by, :update_sql
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
class << self
|
11
|
+
def execute(relation, ...)
|
12
|
+
relation.model.with_connection do |c|
|
13
|
+
new(relation, c, ...).execute
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(relation, connection, inserts, on_duplicate:, update_only: nil, returning: nil, unique_by: nil, record_timestamps: nil)
|
19
|
+
@relation = relation
|
20
|
+
@model, @connection, @inserts = relation.model, connection, inserts.map(&:stringify_keys)
|
12
21
|
@on_duplicate, @update_only, @returning, @unique_by = on_duplicate, update_only, returning, unique_by
|
13
22
|
@record_timestamps = record_timestamps.nil? ? model.record_timestamps : record_timestamps
|
14
23
|
|
@@ -23,10 +32,8 @@ module ActiveRecord
|
|
23
32
|
@keys = @inserts.first.keys
|
24
33
|
end
|
25
34
|
|
26
|
-
|
27
|
-
|
28
|
-
@keys |= @scope_attributes.keys
|
29
|
-
end
|
35
|
+
@scope_attributes = relation.scope_for_create.except(@model.inheritance_column)
|
36
|
+
@keys |= @scope_attributes.keys
|
30
37
|
@keys = @keys.to_set
|
31
38
|
|
32
39
|
@returning = (connection.supports_insert_returning? ? primary_keys : false) if @returning.nil?
|
@@ -52,10 +59,9 @@ module ActiveRecord
|
|
52
59
|
end
|
53
60
|
|
54
61
|
def primary_keys
|
55
|
-
Array(
|
62
|
+
Array(@model.schema_cache.primary_keys(model.table_name))
|
56
63
|
end
|
57
64
|
|
58
|
-
|
59
65
|
def skip_duplicates?
|
60
66
|
on_duplicate == :skip
|
61
67
|
end
|
@@ -67,7 +73,7 @@ module ActiveRecord
|
|
67
73
|
def map_key_with_value
|
68
74
|
inserts.map do |attributes|
|
69
75
|
attributes = attributes.stringify_keys
|
70
|
-
attributes.merge!(scope_attributes)
|
76
|
+
attributes.merge!(@scope_attributes)
|
71
77
|
attributes.reverse_merge!(timestamps_for_create) if record_timestamps?
|
72
78
|
|
73
79
|
verify_attributes(attributes)
|
@@ -92,8 +98,6 @@ module ActiveRecord
|
|
92
98
|
end
|
93
99
|
|
94
100
|
private
|
95
|
-
attr_reader :scope_attributes
|
96
|
-
|
97
101
|
def has_attribute_aliases?(attributes)
|
98
102
|
attributes.keys.any? { |attribute| model.attribute_alias?(attribute) }
|
99
103
|
end
|
@@ -163,10 +167,9 @@ module ActiveRecord
|
|
163
167
|
end
|
164
168
|
|
165
169
|
def unique_indexes
|
166
|
-
|
170
|
+
@model.schema_cache.indexes(model.table_name).select(&:unique)
|
167
171
|
end
|
168
172
|
|
169
|
-
|
170
173
|
def ensure_valid_options_for_connection!
|
171
174
|
if returning && !connection.supports_insert_returning?
|
172
175
|
raise ArgumentError, "#{connection.class} does not support :returning"
|
@@ -192,7 +195,7 @@ module ActiveRecord
|
|
192
195
|
|
193
196
|
|
194
197
|
def readonly_columns
|
195
|
-
primary_keys + model.readonly_attributes
|
198
|
+
primary_keys + model.readonly_attributes
|
196
199
|
end
|
197
200
|
|
198
201
|
def unique_by_columns
|
@@ -301,7 +304,7 @@ module ActiveRecord
|
|
301
304
|
end
|
302
305
|
|
303
306
|
def extract_types_from_columns_on(table_name, keys:)
|
304
|
-
columns =
|
307
|
+
columns = @model.schema_cache.columns_hash(table_name)
|
305
308
|
|
306
309
|
unknown_column = (keys - columns.keys).first
|
307
310
|
raise UnknownAttributeError.new(model.new, unknown_column) if unknown_column
|
@@ -178,7 +178,10 @@ module ActiveRecord
|
|
178
178
|
def can_use_fast_cache_version?(timestamp)
|
179
179
|
timestamp.is_a?(String) &&
|
180
180
|
cache_timestamp_format == :usec &&
|
181
|
-
|
181
|
+
# FIXME: checking out a connection for this is wasteful
|
182
|
+
# we should store/cache this information in the schema cache
|
183
|
+
# or similar.
|
184
|
+
self.class.with_connection(&:default_timezone) == :utc &&
|
182
185
|
!updated_at_came_from_user?
|
183
186
|
end
|
184
187
|
|
@@ -13,17 +13,13 @@ module ActiveRecord
|
|
13
13
|
class NullInternalMetadata # :nodoc:
|
14
14
|
end
|
15
15
|
|
16
|
-
attr_reader :
|
16
|
+
attr_reader :arel_table
|
17
17
|
|
18
|
-
def initialize(
|
19
|
-
@
|
18
|
+
def initialize(pool)
|
19
|
+
@pool = pool
|
20
20
|
@arel_table = Arel::Table.new(table_name)
|
21
21
|
end
|
22
22
|
|
23
|
-
def enabled?
|
24
|
-
connection.use_metadata_table?
|
25
|
-
end
|
26
|
-
|
27
23
|
def primary_key
|
28
24
|
"key"
|
29
25
|
end
|
@@ -36,50 +32,66 @@ module ActiveRecord
|
|
36
32
|
"#{ActiveRecord::Base.table_name_prefix}#{ActiveRecord::Base.internal_metadata_table_name}#{ActiveRecord::Base.table_name_suffix}"
|
37
33
|
end
|
38
34
|
|
35
|
+
def enabled?
|
36
|
+
@pool.db_config.use_metadata_table?
|
37
|
+
end
|
38
|
+
|
39
39
|
def []=(key, value)
|
40
40
|
return unless enabled?
|
41
41
|
|
42
|
-
|
42
|
+
@pool.with_connection do |connection|
|
43
|
+
update_or_create_entry(connection, key, value)
|
44
|
+
end
|
43
45
|
end
|
44
46
|
|
45
47
|
def [](key)
|
46
48
|
return unless enabled?
|
47
49
|
|
48
|
-
|
49
|
-
entry
|
50
|
+
@pool.with_connection do |connection|
|
51
|
+
if entry = select_entry(connection, key)
|
52
|
+
entry[value_key]
|
53
|
+
end
|
50
54
|
end
|
51
55
|
end
|
52
56
|
|
53
57
|
def delete_all_entries
|
54
58
|
dm = Arel::DeleteManager.new(arel_table)
|
55
59
|
|
56
|
-
|
60
|
+
@pool.with_connection do |connection|
|
61
|
+
connection.delete(dm, "#{self.class} Destroy")
|
62
|
+
end
|
57
63
|
end
|
58
64
|
|
59
65
|
def count
|
60
66
|
sm = Arel::SelectManager.new(arel_table)
|
61
67
|
sm.project(*Arel::Nodes::Count.new([Arel.star]))
|
62
68
|
|
63
|
-
|
69
|
+
@pool.with_connection do |connection|
|
70
|
+
connection.select_values(sm, "#{self.class} Count").first
|
71
|
+
end
|
64
72
|
end
|
65
73
|
|
66
74
|
def create_table_and_set_flags(environment, schema_sha1 = nil)
|
67
75
|
return unless enabled?
|
68
76
|
|
69
|
-
|
70
|
-
|
71
|
-
|
77
|
+
@pool.with_connection do |connection|
|
78
|
+
create_table
|
79
|
+
update_or_create_entry(connection, :environment, environment)
|
80
|
+
update_or_create_entry(connection, :schema_sha1, schema_sha1) if schema_sha1
|
81
|
+
end
|
72
82
|
end
|
73
83
|
|
74
84
|
# Creates an internal metadata table with columns +key+ and +value+
|
75
85
|
def create_table
|
76
86
|
return unless enabled?
|
77
87
|
|
78
|
-
|
79
|
-
connection.
|
80
|
-
|
81
|
-
|
82
|
-
|
88
|
+
@pool.with_connection do |connection|
|
89
|
+
unless connection.table_exists?(table_name)
|
90
|
+
connection.create_table(table_name, id: false) do |t|
|
91
|
+
t.string :key, **connection.internal_string_options_for_primary_key
|
92
|
+
t.string :value
|
93
|
+
t.timestamps
|
94
|
+
end
|
83
95
|
end
|
84
96
|
end
|
85
97
|
end
|
@@ -87,49 +99,51 @@ module ActiveRecord
|
|
87
99
|
def drop_table
|
88
100
|
return unless enabled?
|
89
101
|
|
90
|
-
|
102
|
+
@pool.with_connection do |connection|
|
103
|
+
connection.drop_table table_name, if_exists: true
|
104
|
+
end
|
91
105
|
end
|
92
106
|
|
93
107
|
def table_exists?
|
94
|
-
|
108
|
+
@pool.schema_cache.data_source_exists?(table_name)
|
95
109
|
end
|
96
110
|
|
97
111
|
private
|
98
|
-
def update_or_create_entry(key, value)
|
99
|
-
entry = select_entry(key)
|
112
|
+
def update_or_create_entry(connection, key, value)
|
113
|
+
entry = select_entry(connection, key)
|
100
114
|
|
101
115
|
if entry
|
102
116
|
if entry[value_key] != value
|
103
|
-
update_entry(key, value)
|
117
|
+
update_entry(connection, key, value)
|
104
118
|
else
|
105
119
|
entry[value_key]
|
106
120
|
end
|
107
121
|
else
|
108
|
-
create_entry(key, value)
|
122
|
+
create_entry(connection, key, value)
|
109
123
|
end
|
110
124
|
end
|
111
125
|
|
112
|
-
def current_time
|
126
|
+
def current_time(connection)
|
113
127
|
connection.default_timezone == :utc ? Time.now.utc : Time.now
|
114
128
|
end
|
115
129
|
|
116
|
-
def create_entry(key, value)
|
130
|
+
def create_entry(connection, key, value)
|
117
131
|
im = Arel::InsertManager.new(arel_table)
|
118
132
|
im.insert [
|
119
133
|
[arel_table[primary_key], key],
|
120
134
|
[arel_table[value_key], value],
|
121
|
-
[arel_table[:created_at], current_time],
|
122
|
-
[arel_table[:updated_at], current_time]
|
135
|
+
[arel_table[:created_at], current_time(connection)],
|
136
|
+
[arel_table[:updated_at], current_time(connection)]
|
123
137
|
]
|
124
138
|
|
125
139
|
connection.insert(im, "#{self.class} Create", primary_key, key)
|
126
140
|
end
|
127
141
|
|
128
|
-
def update_entry(key, new_value)
|
142
|
+
def update_entry(connection, key, new_value)
|
129
143
|
um = Arel::UpdateManager.new(arel_table)
|
130
144
|
um.set [
|
131
145
|
[arel_table[value_key], new_value],
|
132
|
-
[arel_table[:updated_at], current_time]
|
146
|
+
[arel_table[:updated_at], current_time(connection)]
|
133
147
|
]
|
134
148
|
|
135
149
|
um.where(arel_table[primary_key].eq(key))
|
@@ -137,9 +151,9 @@ module ActiveRecord
|
|
137
151
|
connection.update(um, "#{self.class} Update")
|
138
152
|
end
|
139
153
|
|
140
|
-
def select_entry(key)
|
154
|
+
def select_entry(connection, key)
|
141
155
|
sm = Arel::SelectManager.new(arel_table)
|
142
|
-
sm.project(Arel::Nodes::SqlLiteral.new("*"))
|
156
|
+
sm.project(Arel::Nodes::SqlLiteral.new("*", retryable: true))
|
143
157
|
sm.where(arel_table[primary_key].eq(Arel::Nodes::BindParam.new(key)))
|
144
158
|
sm.order(arel_table[primary_key].asc)
|
145
159
|
sm.limit = 1
|
@@ -14,7 +14,7 @@ module ActiveRecord
|
|
14
14
|
# == Usage
|
15
15
|
#
|
16
16
|
# Active Record supports optimistic locking if the +lock_version+ field is present. Each update to the
|
17
|
-
# record increments the +lock_version+
|
17
|
+
# record increments the integer column +lock_version+ and the locking facilities ensure that records instantiated twice
|
18
18
|
# will let the last one saved raise a +StaleObjectError+ if the first was also updated. Example:
|
19
19
|
#
|
20
20
|
# p1 = Person.find(1)
|
@@ -182,14 +182,15 @@ module ActiveRecord
|
|
182
182
|
super
|
183
183
|
end
|
184
184
|
|
185
|
-
|
186
|
-
|
187
|
-
|
185
|
+
private
|
186
|
+
def hook_attribute_type(name, cast_type)
|
187
|
+
if lock_optimistically && name == locking_column
|
188
|
+
cast_type = LockingType.new(cast_type)
|
189
|
+
end
|
190
|
+
|
191
|
+
super
|
188
192
|
end
|
189
|
-
super
|
190
|
-
end
|
191
193
|
|
192
|
-
private
|
193
194
|
def inherited(base)
|
194
195
|
super
|
195
196
|
base.class_eval do
|
@@ -6,27 +6,6 @@ module ActiveRecord
|
|
6
6
|
|
7
7
|
class_attribute :backtrace_cleaner, default: ActiveSupport::BacktraceCleaner.new
|
8
8
|
|
9
|
-
def self.runtime=(value)
|
10
|
-
ActiveRecord.deprecator.warn(<<-MSG.squish)
|
11
|
-
ActiveRecord::LogSubscriber.runtime= is deprecated and will be removed in Rails 7.2.
|
12
|
-
MSG
|
13
|
-
ActiveRecord::RuntimeRegistry.sql_runtime = value
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.runtime
|
17
|
-
ActiveRecord.deprecator.warn(<<-MSG.squish)
|
18
|
-
ActiveRecord::LogSubscriber.runtime is deprecated and will be removed in Rails 7.2.
|
19
|
-
MSG
|
20
|
-
ActiveRecord::RuntimeRegistry.sql_runtime
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.reset_runtime
|
24
|
-
ActiveRecord.deprecator.warn(<<-MSG.squish)
|
25
|
-
ActiveRecord::LogSubscriber.reset_runtime is deprecated and will be removed in Rails 7.2.
|
26
|
-
MSG
|
27
|
-
ActiveRecord::RuntimeRegistry.reset
|
28
|
-
end
|
29
|
-
|
30
9
|
def strict_loading_violation(event)
|
31
10
|
debug do
|
32
11
|
owner = event.payload[:owner]
|
@@ -25,7 +25,10 @@ module ActiveRecord
|
|
25
25
|
payload = [attributes_for_database, new_record?]
|
26
26
|
|
27
27
|
cached_associations = self.class.reflect_on_all_associations.select do |reflection|
|
28
|
-
association_cached?(reflection.name)
|
28
|
+
if association_cached?(reflection.name)
|
29
|
+
association = association(reflection.name)
|
30
|
+
association.loaded? || association.target.present?
|
31
|
+
end
|
29
32
|
end
|
30
33
|
|
31
34
|
unless cached_associations.empty?
|
@@ -79,8 +79,8 @@ module ActiveRecord
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def add_cached_associations(record, entry)
|
82
|
-
record.class.
|
83
|
-
if record.association_cached?(reflection.name)
|
82
|
+
record.class.normalized_reflections.each_value do |reflection|
|
83
|
+
if record.association_cached?(reflection.name) && record.association(reflection.name).loaded?
|
84
84
|
entry << reflection.name << encode(record.association(reflection.name).target)
|
85
85
|
end
|
86
86
|
end
|
@@ -377,14 +377,13 @@ module ActiveRecord
|
|
377
377
|
end
|
378
378
|
|
379
379
|
# Forwards any missing method call to the \target.
|
380
|
-
def method_missing(method,
|
380
|
+
def method_missing(method, ...)
|
381
381
|
if delegate.respond_to?(method)
|
382
|
-
delegate.public_send(method,
|
382
|
+
delegate.public_send(method, ...)
|
383
383
|
else
|
384
384
|
super
|
385
385
|
end
|
386
386
|
end
|
387
|
-
ruby2_keywords(:method_missing)
|
388
387
|
end
|
389
388
|
end
|
390
389
|
end
|
@@ -21,8 +21,7 @@ module ActiveRecord
|
|
21
21
|
# New migration functionality that will never be backward compatible should be added directly to `ActiveRecord::Migration`.
|
22
22
|
#
|
23
23
|
# There are classes for each prior Rails version. Each class descends from the *next* Rails version, so:
|
24
|
-
# 7.0 < 7.1
|
25
|
-
# 5.2 < 6.0 < 6.1 < 7.0 < 7.1
|
24
|
+
# 5.2 < 6.0 < 6.1 < 7.0 < 7.1 < 7.2
|
26
25
|
#
|
27
26
|
# If you are introducing new migration functionality that should only apply from Rails 7 onward, then you should
|
28
27
|
# find the class that immediately precedes it (6.1), and override the relevant migration methods to undo your changes.
|
@@ -30,7 +29,10 @@ module ActiveRecord
|
|
30
29
|
# For example, Rails 6 added a default value for the `precision` option on datetime columns. So in this file, the `V5_2`
|
31
30
|
# class sets the value of `precision` to `nil` if it's not explicitly provided. This way, the default value will not apply
|
32
31
|
# for migrations written for 5.2, but will for migrations written for 6.0.
|
33
|
-
|
32
|
+
V7_2 = Current
|
33
|
+
|
34
|
+
class V7_1 < V7_2
|
35
|
+
end
|
34
36
|
|
35
37
|
class V7_0 < V7_1
|
36
38
|
module LegacyIndexName
|
@@ -80,6 +82,11 @@ module ActiveRecord
|
|
80
82
|
super
|
81
83
|
end
|
82
84
|
|
85
|
+
def references(*args, **options)
|
86
|
+
options[:_skip_validate_options] = true
|
87
|
+
super
|
88
|
+
end
|
89
|
+
|
83
90
|
private
|
84
91
|
def raise_on_if_exist_options(options)
|
85
92
|
end
|
@@ -112,6 +119,7 @@ module ActiveRecord
|
|
112
119
|
|
113
120
|
def rename_table(table_name, new_name, **options)
|
114
121
|
options[:_uses_legacy_table_name] = true
|
122
|
+
options[:_uses_legacy_index_name] = true
|
115
123
|
super
|
116
124
|
end
|
117
125
|
|
@@ -6,13 +6,12 @@ module ActiveRecord
|
|
6
6
|
# to the connection adapter.
|
7
7
|
class DefaultStrategy < ExecutionStrategy # :nodoc:
|
8
8
|
private
|
9
|
-
def method_missing(method,
|
10
|
-
connection.send(method,
|
9
|
+
def method_missing(method, ...)
|
10
|
+
connection.send(method, ...)
|
11
11
|
end
|
12
|
-
ruby2_keywords(:method_missing)
|
13
12
|
|
14
|
-
def respond_to_missing?(method,
|
15
|
-
connection.respond_to?(method) || super
|
13
|
+
def respond_to_missing?(method, include_private = false)
|
14
|
+
connection.respond_to?(method, include_private) || super
|
16
15
|
end
|
17
16
|
|
18
17
|
def connection
|
@@ -2,10 +2,10 @@
|
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
class PendingMigrationConnection # :nodoc:
|
5
|
-
def self.
|
5
|
+
def self.with_temporary_pool(db_config, &block)
|
6
6
|
pool = ActiveRecord::Base.connection_handler.establish_connection(db_config, owner_name: self)
|
7
7
|
|
8
|
-
yield pool
|
8
|
+
yield pool
|
9
9
|
ensure
|
10
10
|
ActiveRecord::Base.connection_handler.remove_connection_pool(self.name)
|
11
11
|
end
|