activerecord 6.1.7.10 → 7.0.0.alpha1
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.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +726 -1404
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/active_record/aggregations.rb +1 -1
- data/lib/active_record/association_relation.rb +0 -10
- data/lib/active_record/associations/association.rb +31 -9
- data/lib/active_record/associations/association_scope.rb +1 -3
- data/lib/active_record/associations/belongs_to_association.rb +15 -4
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
- data/lib/active_record/associations/builder/association.rb +8 -2
- data/lib/active_record/associations/builder/belongs_to.rb +19 -6
- data/lib/active_record/associations/builder/collection_association.rb +1 -1
- data/lib/active_record/associations/builder/has_many.rb +3 -2
- data/lib/active_record/associations/builder/has_one.rb +2 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -2
- data/lib/active_record/associations/collection_association.rb +14 -23
- data/lib/active_record/associations/collection_proxy.rb +8 -3
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +2 -1
- data/lib/active_record/associations/has_one_association.rb +10 -7
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/preloader/association.rb +161 -47
- data/lib/active_record/associations/preloader/batch.rb +51 -0
- data/lib/active_record/associations/preloader/branch.rb +147 -0
- data/lib/active_record/associations/preloader/through_association.rb +37 -11
- data/lib/active_record/associations/preloader.rb +46 -110
- data/lib/active_record/associations/singular_association.rb +8 -2
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +76 -81
- data/lib/active_record/asynchronous_queries_tracker.rb +57 -0
- data/lib/active_record/attribute_assignment.rb +1 -1
- data/lib/active_record/attribute_methods/before_type_cast.rb +7 -2
- data/lib/active_record/attribute_methods/dirty.rb +41 -16
- data/lib/active_record/attribute_methods/primary_key.rb +2 -2
- data/lib/active_record/attribute_methods/query.rb +2 -2
- data/lib/active_record/attribute_methods/read.rb +7 -5
- data/lib/active_record/attribute_methods/serialization.rb +66 -12
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
- data/lib/active_record/attribute_methods/write.rb +7 -10
- data/lib/active_record/attribute_methods.rb +6 -9
- data/lib/active_record/attributes.rb +24 -35
- data/lib/active_record/autosave_association.rb +3 -18
- data/lib/active_record/base.rb +19 -1
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/coders/yaml_column.rb +2 -14
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +312 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +31 -558
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +45 -21
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
- data/lib/active_record/connection_adapters/abstract/quoting.rb +12 -14
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +30 -13
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +60 -16
- data/lib/active_record/connection_adapters/abstract/transaction.rb +3 -3
- data/lib/active_record/connection_adapters/abstract_adapter.rb +112 -66
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +96 -81
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +33 -23
- data/lib/active_record/connection_adapters/mysql/quoting.rb +16 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +1 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -6
- data/lib/active_record/connection_adapters/pool_config.rb +1 -3
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +19 -14
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +6 -32
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +32 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +12 -12
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +159 -102
- data/lib/active_record/connection_adapters/schema_cache.rb +36 -37
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +23 -19
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +4 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -30
- data/lib/active_record/connection_adapters.rb +6 -5
- data/lib/active_record/connection_handling.rb +20 -38
- data/lib/active_record/core.rb +111 -125
- data/lib/active_record/database_configurations/connection_url_resolver.rb +0 -1
- data/lib/active_record/database_configurations/database_config.rb +12 -0
- data/lib/active_record/database_configurations/hash_config.rb +27 -1
- data/lib/active_record/database_configurations/url_config.rb +2 -2
- data/lib/active_record/database_configurations.rb +17 -9
- data/lib/active_record/delegated_type.rb +33 -11
- data/lib/active_record/destroy_association_async_job.rb +1 -1
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
- data/lib/active_record/encryption/cipher.rb +53 -0
- data/lib/active_record/encryption/config.rb +44 -0
- data/lib/active_record/encryption/configurable.rb +61 -0
- data/lib/active_record/encryption/context.rb +35 -0
- data/lib/active_record/encryption/contexts.rb +72 -0
- data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
- data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
- data/lib/active_record/encryption/encryptable_record.rb +208 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
- data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
- data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
- data/lib/active_record/encryption/encryptor.rb +155 -0
- data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
- data/lib/active_record/encryption/errors.rb +15 -0
- data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +29 -0
- data/lib/active_record/encryption/key.rb +28 -0
- data/lib/active_record/encryption/key_generator.rb +42 -0
- data/lib/active_record/encryption/key_provider.rb +46 -0
- data/lib/active_record/encryption/message.rb +33 -0
- data/lib/active_record/encryption/message_serializer.rb +80 -0
- data/lib/active_record/encryption/null_encryptor.rb +21 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
- data/lib/active_record/encryption/scheme.rb +99 -0
- data/lib/active_record/encryption.rb +55 -0
- data/lib/active_record/enum.rb +41 -41
- data/lib/active_record/errors.rb +66 -3
- data/lib/active_record/fixture_set/file.rb +15 -1
- data/lib/active_record/fixture_set/table_row.rb +40 -5
- data/lib/active_record/fixture_set/table_rows.rb +4 -4
- data/lib/active_record/fixtures.rb +16 -11
- data/lib/active_record/future_result.rb +139 -0
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +55 -17
- data/lib/active_record/insert_all.rb +34 -5
- data/lib/active_record/integration.rb +1 -1
- data/lib/active_record/internal_metadata.rb +1 -5
- data/lib/active_record/locking/optimistic.rb +10 -9
- data/lib/active_record/log_subscriber.rb +6 -2
- data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
- data/lib/active_record/middleware/database_selector.rb +8 -3
- data/lib/active_record/migration/command_recorder.rb +4 -4
- data/lib/active_record/migration/compatibility.rb +89 -10
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration.rb +109 -79
- data/lib/active_record/model_schema.rb +45 -31
- data/lib/active_record/nested_attributes.rb +3 -3
- data/lib/active_record/no_touching.rb +2 -2
- data/lib/active_record/null_relation.rb +2 -6
- data/lib/active_record/persistence.rb +134 -45
- data/lib/active_record/query_cache.rb +2 -2
- data/lib/active_record/query_logs.rb +203 -0
- data/lib/active_record/querying.rb +15 -5
- data/lib/active_record/railtie.rb +117 -17
- data/lib/active_record/railties/controller_runtime.rb +1 -1
- data/lib/active_record/railties/databases.rake +72 -48
- data/lib/active_record/readonly_attributes.rb +11 -0
- data/lib/active_record/reflection.rb +45 -44
- data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
- data/lib/active_record/relation/batches.rb +3 -3
- data/lib/active_record/relation/calculations.rb +39 -26
- data/lib/active_record/relation/delegation.rb +6 -6
- data/lib/active_record/relation/finder_methods.rb +31 -22
- data/lib/active_record/relation/merger.rb +20 -13
- data/lib/active_record/relation/predicate_builder.rb +1 -6
- data/lib/active_record/relation/query_attribute.rb +5 -11
- data/lib/active_record/relation/query_methods.rb +230 -49
- data/lib/active_record/relation/record_fetch_warning.rb +2 -2
- data/lib/active_record/relation/spawn_methods.rb +2 -2
- data/lib/active_record/relation/where_clause.rb +8 -4
- data/lib/active_record/relation.rb +166 -77
- data/lib/active_record/result.rb +17 -2
- data/lib/active_record/runtime_registry.rb +2 -4
- data/lib/active_record/sanitization.rb +11 -7
- data/lib/active_record/schema_dumper.rb +3 -3
- data/lib/active_record/schema_migration.rb +0 -4
- data/lib/active_record/scoping/default.rb +61 -12
- data/lib/active_record/scoping/named.rb +3 -11
- data/lib/active_record/scoping.rb +40 -22
- data/lib/active_record/serialization.rb +1 -1
- data/lib/active_record/signed_id.rb +1 -1
- data/lib/active_record/store.rb +1 -6
- data/lib/active_record/tasks/database_tasks.rb +106 -22
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/postgresql_database_tasks.rb +14 -11
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +9 -13
- data/lib/active_record/timestamp.rb +3 -4
- data/lib/active_record/transactions.rb +9 -14
- data/lib/active_record/translation.rb +2 -2
- data/lib/active_record/type/adapter_specific_registry.rb +32 -7
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
- data/lib/active_record/type/internal/timezone.rb +2 -2
- data/lib/active_record/type/serialized.rb +1 -1
- data/lib/active_record/type/type_map.rb +17 -20
- data/lib/active_record/type.rb +1 -2
- data/lib/active_record/validations/associated.rb +1 -1
- data/lib/active_record.rb +170 -2
- data/lib/arel/attributes/attribute.rb +0 -8
- data/lib/arel/crud.rb +18 -22
- data/lib/arel/delete_manager.rb +2 -4
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/casted.rb +1 -1
- data/lib/arel/nodes/delete_statement.rb +8 -13
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/select_core.rb +2 -2
- data/lib/arel/nodes/select_statement.rb +2 -2
- data/lib/arel/nodes/update_statement.rb +3 -2
- data/lib/arel/predications.rb +1 -1
- data/lib/arel/select_manager.rb +10 -4
- data/lib/arel/table.rb +0 -1
- data/lib/arel/tree_manager.rb +0 -12
- data/lib/arel/update_manager.rb +2 -4
- data/lib/arel/visitors/dot.rb +80 -90
- data/lib/arel/visitors/mysql.rb +6 -1
- data/lib/arel/visitors/postgresql.rb +0 -10
- data/lib/arel/visitors/to_sql.rb +43 -2
- data/lib/arel.rb +1 -1
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
- metadata +52 -14
@@ -14,7 +14,7 @@ module ActiveRecord
|
|
14
14
|
ActiveRecord::Base.configurations.configs_for(env_name: env_name).each do |db_config|
|
15
15
|
db_config._database = "#{db_config.database}-#{i}"
|
16
16
|
|
17
|
-
ActiveRecord::Tasks::DatabaseTasks.reconstruct_from_schema(db_config, ActiveRecord
|
17
|
+
ActiveRecord::Tasks::DatabaseTasks.reconstruct_from_schema(db_config, ActiveRecord.schema_format, nil)
|
18
18
|
end
|
19
19
|
ensure
|
20
20
|
ActiveRecord::Base.establish_connection
|
@@ -134,7 +134,7 @@ module ActiveRecord
|
|
134
134
|
@connection_subscriber = ActiveSupport::Notifications.subscribe("!connection.active_record") do |_, _, _, _, payload|
|
135
135
|
spec_name = payload[:spec_name] if payload.key?(:spec_name)
|
136
136
|
shard = payload[:shard] if payload.key?(:shard)
|
137
|
-
setup_shared_connection_pool
|
137
|
+
setup_shared_connection_pool
|
138
138
|
|
139
139
|
if spec_name
|
140
140
|
begin
|
@@ -143,14 +143,10 @@ module ActiveRecord
|
|
143
143
|
connection = nil
|
144
144
|
end
|
145
145
|
|
146
|
-
if connection
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
connection.begin_transaction joinable: false, _lazy: false
|
151
|
-
connection.pool.lock_thread = true if lock_threads
|
152
|
-
@fixture_connections << connection
|
153
|
-
end
|
146
|
+
if connection && !@fixture_connections.include?(connection)
|
147
|
+
connection.begin_transaction joinable: false, _lazy: false
|
148
|
+
connection.pool.lock_thread = true if lock_threads
|
149
|
+
@fixture_connections << connection
|
154
150
|
end
|
155
151
|
end
|
156
152
|
end
|
@@ -197,8 +193,8 @@ module ActiveRecord
|
|
197
193
|
# need to share a connection pool so that the reading connection
|
198
194
|
# can see data in the open transaction on the writing connection.
|
199
195
|
def setup_shared_connection_pool
|
200
|
-
if ActiveRecord
|
201
|
-
writing_handler = ActiveRecord::Base.connection_handlers[ActiveRecord
|
196
|
+
if ActiveRecord.legacy_connection_handling
|
197
|
+
writing_handler = ActiveRecord::Base.connection_handlers[ActiveRecord.writing_role]
|
202
198
|
|
203
199
|
ActiveRecord::Base.connection_handlers.values.each do |handler|
|
204
200
|
if handler != writing_handler
|
@@ -225,7 +221,7 @@ module ActiveRecord
|
|
225
221
|
handler.connection_pool_names.each do |name|
|
226
222
|
pool_manager = handler.send(:owner_to_pool_manager)[name]
|
227
223
|
pool_manager.shard_names.each do |shard_name|
|
228
|
-
writing_pool_config = pool_manager.get_pool_config(ActiveRecord
|
224
|
+
writing_pool_config = pool_manager.get_pool_config(ActiveRecord.writing_role, shard_name)
|
229
225
|
@saved_pool_configs[name][shard_name] ||= {}
|
230
226
|
pool_manager.role_names.each do |role|
|
231
227
|
next unless pool_config = pool_manager.get_pool_config(role, shard_name)
|
@@ -240,7 +236,7 @@ module ActiveRecord
|
|
240
236
|
end
|
241
237
|
|
242
238
|
def teardown_shared_connection_pool
|
243
|
-
if ActiveRecord
|
239
|
+
if ActiveRecord.legacy_connection_handling
|
244
240
|
@legacy_saved_pool_configs.each_pair do |handler, names|
|
245
241
|
names.each_pair do |name, shards|
|
246
242
|
shards.each_pair do |shard_name, pool_config|
|
@@ -75,7 +75,7 @@ module ActiveRecord
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def current_time_from_proper_timezone
|
78
|
-
default_timezone == :utc ? Time.now.utc : Time.now
|
78
|
+
ActiveRecord.default_timezone == :utc ? Time.now.utc : Time.now
|
79
79
|
end
|
80
80
|
|
81
81
|
private
|
@@ -127,7 +127,7 @@ module ActiveRecord
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def should_record_timestamps?
|
130
|
-
record_timestamps && (!
|
130
|
+
record_timestamps && (!partial_updates? || has_changes_to_save?)
|
131
131
|
end
|
132
132
|
|
133
133
|
def timestamp_attributes_for_create_in_model
|
@@ -148,8 +148,7 @@ module ActiveRecord
|
|
148
148
|
|
149
149
|
def max_updated_column_timestamp
|
150
150
|
timestamp_attributes_for_update_in_model
|
151
|
-
.
|
152
|
-
.compact
|
151
|
+
.filter_map { |attr| self[attr]&.to_time }
|
153
152
|
.max
|
154
153
|
end
|
155
154
|
|
@@ -4,7 +4,7 @@ module ActiveRecord
|
|
4
4
|
# See ActiveRecord::Transactions::ClassMethods for documentation.
|
5
5
|
module Transactions
|
6
6
|
extend ActiveSupport::Concern
|
7
|
-
|
7
|
+
# :nodoc:
|
8
8
|
ACTIONS = [:create, :destroy, :update]
|
9
9
|
|
10
10
|
included do
|
@@ -290,19 +290,19 @@ module ActiveRecord
|
|
290
290
|
self.class.transaction(**options, &block)
|
291
291
|
end
|
292
292
|
|
293
|
-
def destroy
|
293
|
+
def destroy # :nodoc:
|
294
294
|
with_transaction_returning_status { super }
|
295
295
|
end
|
296
296
|
|
297
|
-
def save(**)
|
297
|
+
def save(**) # :nodoc:
|
298
298
|
with_transaction_returning_status { super }
|
299
299
|
end
|
300
300
|
|
301
|
-
def save!(**)
|
301
|
+
def save!(**) # :nodoc:
|
302
302
|
with_transaction_returning_status { super }
|
303
303
|
end
|
304
304
|
|
305
|
-
def touch(*, **)
|
305
|
+
def touch(*, **) # :nodoc:
|
306
306
|
with_transaction_returning_status { super }
|
307
307
|
end
|
308
308
|
|
@@ -314,8 +314,8 @@ module ActiveRecord
|
|
314
314
|
#
|
315
315
|
# Ensure that it is not called if the object was never persisted (failed create),
|
316
316
|
# but call it after the commit of a destroyed object.
|
317
|
-
def committed!(should_run_callbacks: true)
|
318
|
-
|
317
|
+
def committed!(should_run_callbacks: true) # :nodoc:
|
318
|
+
@_start_transaction_state = nil
|
319
319
|
if should_run_callbacks
|
320
320
|
@_committed_already_called = true
|
321
321
|
_run_commit_callbacks
|
@@ -326,7 +326,7 @@ module ActiveRecord
|
|
326
326
|
|
327
327
|
# Call the #after_rollback callbacks. The +force_restore_state+ argument indicates if the record
|
328
328
|
# state should be rolled back to the beginning or just to the last savepoint.
|
329
|
-
def rolledback!(force_restore_state: false, should_run_callbacks: true)
|
329
|
+
def rolledback!(force_restore_state: false, should_run_callbacks: true) # :nodoc:
|
330
330
|
if should_run_callbacks
|
331
331
|
_run_rollback_callbacks
|
332
332
|
end
|
@@ -389,12 +389,7 @@ module ActiveRecord
|
|
389
389
|
def clear_transaction_record_state
|
390
390
|
return unless @_start_transaction_state
|
391
391
|
@_start_transaction_state[:level] -= 1
|
392
|
-
|
393
|
-
end
|
394
|
-
|
395
|
-
# Force to clear the transaction record state.
|
396
|
-
def force_clear_transaction_record_state
|
397
|
-
@_start_transaction_state = nil
|
392
|
+
@_start_transaction_state = nil if @_start_transaction_state[:level] < 1
|
398
393
|
end
|
399
394
|
|
400
395
|
# Restore the new record state and id of a record that was previously saved by a call to save_record_state.
|
@@ -5,7 +5,7 @@ module ActiveRecord
|
|
5
5
|
include ActiveModel::Translation
|
6
6
|
|
7
7
|
# Set the lookup ancestors for ActiveModel.
|
8
|
-
def lookup_ancestors
|
8
|
+
def lookup_ancestors # :nodoc:
|
9
9
|
klass = self
|
10
10
|
classes = [klass]
|
11
11
|
return classes if klass == ActiveRecord::Base
|
@@ -17,7 +17,7 @@ module ActiveRecord
|
|
17
17
|
end
|
18
18
|
|
19
19
|
# Set the i18n scope to overwrite ActiveModel.
|
20
|
-
def i18n_scope
|
20
|
+
def i18n_scope # :nodoc:
|
21
21
|
:activerecord
|
22
22
|
end
|
23
23
|
end
|
@@ -5,15 +5,40 @@ require "active_model/type/registry"
|
|
5
5
|
module ActiveRecord
|
6
6
|
# :stopdoc:
|
7
7
|
module Type
|
8
|
-
class AdapterSpecificRegistry
|
8
|
+
class AdapterSpecificRegistry # :nodoc:
|
9
|
+
def initialize
|
10
|
+
@registrations = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize_copy(other)
|
14
|
+
@registrations = @registrations.dup
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
9
18
|
def add_modifier(options, klass, **args)
|
10
19
|
registrations << DecorationRegistration.new(options, klass, **args)
|
11
20
|
end
|
12
21
|
|
13
|
-
|
14
|
-
|
15
|
-
|
22
|
+
def register(type_name, klass = nil, **options, &block)
|
23
|
+
unless block_given?
|
24
|
+
block = proc { |_, *args| klass.new(*args) }
|
25
|
+
block.ruby2_keywords if block.respond_to?(:ruby2_keywords)
|
16
26
|
end
|
27
|
+
registrations << Registration.new(type_name, block, **options)
|
28
|
+
end
|
29
|
+
|
30
|
+
def lookup(symbol, *args, **kwargs)
|
31
|
+
registration = find_registration(symbol, *args, **kwargs)
|
32
|
+
|
33
|
+
if registration
|
34
|
+
registration.call(self, symbol, *args, **kwargs)
|
35
|
+
else
|
36
|
+
raise ArgumentError, "Unknown type #{symbol.inspect}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
attr_reader :registrations
|
17
42
|
|
18
43
|
def find_registration(symbol, *args, **kwargs)
|
19
44
|
registrations
|
@@ -22,7 +47,7 @@ module ActiveRecord
|
|
22
47
|
end
|
23
48
|
end
|
24
49
|
|
25
|
-
class Registration
|
50
|
+
class Registration # :nodoc:
|
26
51
|
def initialize(name, block, adapter: nil, override: nil)
|
27
52
|
@name = name
|
28
53
|
@block = block
|
@@ -89,7 +114,7 @@ module ActiveRecord
|
|
89
114
|
end
|
90
115
|
end
|
91
116
|
|
92
|
-
class DecorationRegistration < Registration
|
117
|
+
class DecorationRegistration < Registration # :nodoc:
|
93
118
|
def initialize(options, klass, adapter: nil)
|
94
119
|
@options = options
|
95
120
|
@klass = klass
|
@@ -120,7 +145,7 @@ module ActiveRecord
|
|
120
145
|
end
|
121
146
|
end
|
122
147
|
|
123
|
-
class TypeConflictError < StandardError
|
148
|
+
class TypeConflictError < StandardError # :nodoc:
|
124
149
|
end
|
125
150
|
# :startdoc:
|
126
151
|
end
|
@@ -2,7 +2,40 @@
|
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
module Type
|
5
|
-
class HashLookupTypeMap
|
5
|
+
class HashLookupTypeMap # :nodoc:
|
6
|
+
def initialize(parent = nil)
|
7
|
+
@mapping = {}
|
8
|
+
@cache = Concurrent::Map.new do |h, key|
|
9
|
+
h.fetch_or_store(key, Concurrent::Map.new)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def lookup(lookup_key, *args)
|
14
|
+
fetch(lookup_key, *args) { Type.default_value }
|
15
|
+
end
|
16
|
+
|
17
|
+
def fetch(lookup_key, *args, &block)
|
18
|
+
@cache[lookup_key].fetch_or_store(args) do
|
19
|
+
perform_fetch(lookup_key, *args, &block)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def register_type(key, value = nil, &block)
|
24
|
+
raise ::ArgumentError unless value || block
|
25
|
+
|
26
|
+
if block
|
27
|
+
@mapping[key] = block
|
28
|
+
else
|
29
|
+
@mapping[key] = proc { value }
|
30
|
+
end
|
31
|
+
@cache.clear
|
32
|
+
end
|
33
|
+
|
34
|
+
def clear
|
35
|
+
@mapping.clear
|
36
|
+
@cache.clear
|
37
|
+
end
|
38
|
+
|
6
39
|
def alias_type(type, alias_type)
|
7
40
|
register_type(type) { |_, *args| lookup(alias_type, *args) }
|
8
41
|
end
|
@@ -5,11 +5,11 @@ module ActiveRecord
|
|
5
5
|
module Internal
|
6
6
|
module Timezone
|
7
7
|
def is_utc?
|
8
|
-
ActiveRecord
|
8
|
+
ActiveRecord.default_timezone == :utc
|
9
9
|
end
|
10
10
|
|
11
11
|
def default_timezone
|
12
|
-
ActiveRecord
|
12
|
+
ActiveRecord.default_timezone
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -5,55 +5,52 @@ require "concurrent/map"
|
|
5
5
|
module ActiveRecord
|
6
6
|
module Type
|
7
7
|
class TypeMap # :nodoc:
|
8
|
-
def initialize
|
8
|
+
def initialize(parent = nil)
|
9
9
|
@mapping = {}
|
10
|
-
@
|
11
|
-
|
12
|
-
end
|
10
|
+
@parent = parent
|
11
|
+
@cache = Concurrent::Map.new
|
13
12
|
end
|
14
13
|
|
15
|
-
def lookup(lookup_key
|
16
|
-
fetch(lookup_key
|
14
|
+
def lookup(lookup_key)
|
15
|
+
fetch(lookup_key) { Type.default_value }
|
17
16
|
end
|
18
17
|
|
19
|
-
def fetch(lookup_key,
|
20
|
-
@cache
|
21
|
-
perform_fetch(lookup_key,
|
18
|
+
def fetch(lookup_key, &block)
|
19
|
+
@cache.fetch_or_store(lookup_key) do
|
20
|
+
perform_fetch(lookup_key, &block)
|
22
21
|
end
|
23
22
|
end
|
24
23
|
|
25
24
|
def register_type(key, value = nil, &block)
|
26
25
|
raise ::ArgumentError unless value || block
|
27
|
-
@cache.clear
|
28
26
|
|
29
27
|
if block
|
30
28
|
@mapping[key] = block
|
31
29
|
else
|
32
30
|
@mapping[key] = proc { value }
|
33
31
|
end
|
32
|
+
@cache.clear
|
34
33
|
end
|
35
34
|
|
36
35
|
def alias_type(key, target_key)
|
37
|
-
register_type(key) do |sql_type
|
36
|
+
register_type(key) do |sql_type|
|
38
37
|
metadata = sql_type[/\(.*\)/, 0]
|
39
|
-
lookup("#{target_key}#{metadata}"
|
38
|
+
lookup("#{target_key}#{metadata}")
|
40
39
|
end
|
41
40
|
end
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
def perform_fetch(lookup_key, *args)
|
42
|
+
protected
|
43
|
+
def perform_fetch(lookup_key, &block)
|
49
44
|
matching_pair = @mapping.reverse_each.detect do |key, _|
|
50
45
|
key === lookup_key
|
51
46
|
end
|
52
47
|
|
53
48
|
if matching_pair
|
54
|
-
matching_pair.last.call(lookup_key
|
49
|
+
matching_pair.last.call(lookup_key)
|
50
|
+
elsif @parent
|
51
|
+
@parent.perform_fetch(lookup_key, &block)
|
55
52
|
else
|
56
|
-
yield lookup_key
|
53
|
+
yield lookup_key
|
57
54
|
end
|
58
55
|
end
|
59
56
|
end
|
data/lib/active_record/type.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
module Validations
|
5
|
-
class AssociatedValidator < ActiveModel::EachValidator
|
5
|
+
class AssociatedValidator < ActiveModel::EachValidator # :nodoc:
|
6
6
|
def validate_each(record, attribute, value)
|
7
7
|
if Array(value).reject { |r| valid_object?(r) }.any?
|
8
8
|
record.errors.add(attribute, :invalid, **options.merge(value: value))
|
data/lib/active_record.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c) 2004-
|
4
|
+
# Copyright (c) 2004-2021 David Heinemeier Hansson
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|
@@ -43,6 +43,7 @@ module ActiveRecord
|
|
43
43
|
autoload :CounterCache
|
44
44
|
autoload :DynamicMatchers
|
45
45
|
autoload :DelegatedType
|
46
|
+
autoload :Encryption
|
46
47
|
autoload :Enum
|
47
48
|
autoload :InternalMetadata
|
48
49
|
autoload :Explain
|
@@ -57,6 +58,7 @@ module ActiveRecord
|
|
57
58
|
autoload :Persistence
|
58
59
|
autoload :QueryCache
|
59
60
|
autoload :Querying
|
61
|
+
autoload :QueryLogs
|
60
62
|
autoload :ReadonlyAttributes
|
61
63
|
autoload :RecordInvalid, "active_record/validations"
|
62
64
|
autoload :Reflection
|
@@ -67,7 +69,6 @@ module ActiveRecord
|
|
67
69
|
autoload :SchemaMigration
|
68
70
|
autoload :Scoping
|
69
71
|
autoload :Serialization
|
70
|
-
autoload :StatementCache
|
71
72
|
autoload :Store
|
72
73
|
autoload :SignedId
|
73
74
|
autoload :Suppressor
|
@@ -79,6 +80,7 @@ module ActiveRecord
|
|
79
80
|
autoload :DestroyAssociationAsyncJob
|
80
81
|
|
81
82
|
eager_autoload do
|
83
|
+
autoload :StatementCache
|
82
84
|
autoload :ConnectionAdapters
|
83
85
|
|
84
86
|
autoload :Aggregations
|
@@ -86,11 +88,13 @@ module ActiveRecord
|
|
86
88
|
autoload :AttributeAssignment
|
87
89
|
autoload :AttributeMethods
|
88
90
|
autoload :AutosaveAssociation
|
91
|
+
autoload :AsynchronousQueriesTracker
|
89
92
|
|
90
93
|
autoload :LegacyYamlAdapter
|
91
94
|
|
92
95
|
autoload :Relation
|
93
96
|
autoload :AssociationRelation
|
97
|
+
autoload :DisableJoinsAssociationRelation
|
94
98
|
autoload :NullRelation
|
95
99
|
|
96
100
|
autoload_under "relation" do
|
@@ -104,6 +108,7 @@ module ActiveRecord
|
|
104
108
|
end
|
105
109
|
|
106
110
|
autoload :Result
|
111
|
+
autoload :FutureResult
|
107
112
|
autoload :TableMetadata
|
108
113
|
autoload :Type
|
109
114
|
end
|
@@ -165,6 +170,168 @@ module ActiveRecord
|
|
165
170
|
autoload :TestDatabases, "active_record/test_databases"
|
166
171
|
autoload :TestFixtures, "active_record/fixtures"
|
167
172
|
|
173
|
+
# A list of tables or regex's to match tables to ignore when
|
174
|
+
# dumping the schema cache. For example if this is set to +[/^_/]+
|
175
|
+
# the schema cache will not dump tables named with an underscore.
|
176
|
+
singleton_class.attr_accessor :schema_cache_ignored_tables
|
177
|
+
self.schema_cache_ignored_tables = []
|
178
|
+
|
179
|
+
singleton_class.attr_accessor :legacy_connection_handling
|
180
|
+
self.legacy_connection_handling = true
|
181
|
+
|
182
|
+
##
|
183
|
+
# :singleton-method:
|
184
|
+
# Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
|
185
|
+
# dates and times from the database. This is set to :utc by default.
|
186
|
+
singleton_class.attr_accessor :default_timezone
|
187
|
+
self.default_timezone = :utc
|
188
|
+
|
189
|
+
singleton_class.attr_accessor :writing_role
|
190
|
+
self.writing_role = :writing
|
191
|
+
|
192
|
+
singleton_class.attr_accessor :reading_role
|
193
|
+
self.reading_role = :reading
|
194
|
+
|
195
|
+
# Sets the async_query_executor for an application. By default the thread pool executor
|
196
|
+
# set to +nil+ which will not run queries in the background. Applications must configure
|
197
|
+
# a thread pool executor to use this feature. Options are:
|
198
|
+
#
|
199
|
+
# * nil - Does not initialize a thread pool executor. Any async calls will be
|
200
|
+
# run in the foreground.
|
201
|
+
# * :global_thread_pool - Initializes a single +Concurrent::ThreadPoolExecutor+
|
202
|
+
# that uses the +async_query_concurrency+ for the +max_threads+ value.
|
203
|
+
# * :multi_thread_pool - Initializes a +Concurrent::ThreadPoolExecutor+ for each
|
204
|
+
# database connection. The initializer values are defined in the configuration hash.
|
205
|
+
singleton_class.attr_accessor :async_query_executor
|
206
|
+
self.async_query_executor = nil
|
207
|
+
|
208
|
+
def self.global_thread_pool_async_query_executor # :nodoc:
|
209
|
+
concurrency = global_executor_concurrency || 4
|
210
|
+
@global_thread_pool_async_query_executor ||= Concurrent::ThreadPoolExecutor.new(
|
211
|
+
min_threads: 0,
|
212
|
+
max_threads: concurrency,
|
213
|
+
max_queue: concurrency * 4,
|
214
|
+
fallback_policy: :caller_runs
|
215
|
+
)
|
216
|
+
end
|
217
|
+
|
218
|
+
# Set the +global_executor_concurrency+. This configuration value can only be used
|
219
|
+
# with the global thread pool async query executor.
|
220
|
+
def self.global_executor_concurrency=(global_executor_concurrency)
|
221
|
+
if self.async_query_executor.nil? || self.async_query_executor == :multi_thread_pool
|
222
|
+
raise ArgumentError, "`global_executor_concurrency` cannot be set when using the executor is nil or set to multi_thead_pool. For multiple thread pools, please set the concurrency in your database configuration."
|
223
|
+
end
|
224
|
+
|
225
|
+
@global_executor_concurrency = global_executor_concurrency
|
226
|
+
end
|
227
|
+
|
228
|
+
def self.global_executor_concurrency # :nodoc:
|
229
|
+
@global_executor_concurrency ||= nil
|
230
|
+
end
|
231
|
+
|
232
|
+
singleton_class.attr_accessor :index_nested_attribute_errors
|
233
|
+
self.index_nested_attribute_errors = false
|
234
|
+
|
235
|
+
##
|
236
|
+
# :singleton-method:
|
237
|
+
#
|
238
|
+
# Specifies if the methods calling database queries should be logged below
|
239
|
+
# their relevant queries. Defaults to false.
|
240
|
+
singleton_class.attr_accessor :verbose_query_logs
|
241
|
+
self.verbose_query_logs = false
|
242
|
+
|
243
|
+
##
|
244
|
+
# :singleton-method:
|
245
|
+
#
|
246
|
+
# Specifies the names of the queues used by background jobs.
|
247
|
+
singleton_class.attr_accessor :queues
|
248
|
+
self.queues = {}
|
249
|
+
|
250
|
+
singleton_class.attr_accessor :maintain_test_schema
|
251
|
+
self.maintain_test_schema = nil
|
252
|
+
|
253
|
+
##
|
254
|
+
# :singleton-method:
|
255
|
+
# Specify a threshold for the size of query result sets. If the number of
|
256
|
+
# records in the set exceeds the threshold, a warning is logged. This can
|
257
|
+
# be used to identify queries which load thousands of records and
|
258
|
+
# potentially cause memory bloat.
|
259
|
+
singleton_class.attr_accessor :warn_on_records_fetched_greater_than
|
260
|
+
self.warn_on_records_fetched_greater_than = false
|
261
|
+
|
262
|
+
singleton_class.attr_accessor :application_record_class
|
263
|
+
self.application_record_class = nil
|
264
|
+
|
265
|
+
##
|
266
|
+
# :singleton-method:
|
267
|
+
# Set the application to log or raise when an association violates strict loading.
|
268
|
+
# Defaults to :raise.
|
269
|
+
singleton_class.attr_accessor :action_on_strict_loading_violation
|
270
|
+
self.action_on_strict_loading_violation = :raise
|
271
|
+
|
272
|
+
##
|
273
|
+
# :singleton-method:
|
274
|
+
# Specifies the format to use when dumping the database schema with Rails'
|
275
|
+
# Rakefile. If :sql, the schema is dumped as (potentially database-
|
276
|
+
# specific) SQL statements. If :ruby, the schema is dumped as an
|
277
|
+
# ActiveRecord::Schema file which can be loaded into any database that
|
278
|
+
# supports migrations. Use :ruby if you want to have different database
|
279
|
+
# adapters for, e.g., your development and test environments.
|
280
|
+
singleton_class.attr_accessor :schema_format
|
281
|
+
self.schema_format = :ruby
|
282
|
+
|
283
|
+
##
|
284
|
+
# :singleton-method:
|
285
|
+
# Specifies if an error should be raised if the query has an order being
|
286
|
+
# ignored when doing batch queries. Useful in applications where the
|
287
|
+
# scope being ignored is error-worthy, rather than a warning.
|
288
|
+
singleton_class.attr_accessor :error_on_ignored_order
|
289
|
+
self.error_on_ignored_order = false
|
290
|
+
|
291
|
+
##
|
292
|
+
# :singleton-method:
|
293
|
+
# Specify whether or not to use timestamps for migration versions
|
294
|
+
singleton_class.attr_accessor :timestamped_migrations
|
295
|
+
self.timestamped_migrations = true
|
296
|
+
|
297
|
+
##
|
298
|
+
# :singleton-method:
|
299
|
+
# Specify whether schema dump should happen at the end of the
|
300
|
+
# bin/rails db:migrate command. This is true by default, which is useful for the
|
301
|
+
# development environment. This should ideally be false in the production
|
302
|
+
# environment where dumping schema is rarely needed.
|
303
|
+
singleton_class.attr_accessor :dump_schema_after_migration
|
304
|
+
self.dump_schema_after_migration = true
|
305
|
+
|
306
|
+
##
|
307
|
+
# :singleton-method:
|
308
|
+
# Specifies which database schemas to dump when calling db:schema:dump.
|
309
|
+
# If the value is :schema_search_path (the default), any schemas listed in
|
310
|
+
# schema_search_path are dumped. Use :all to dump all schemas regardless
|
311
|
+
# of schema_search_path, or a string of comma separated schemas for a
|
312
|
+
# custom list.
|
313
|
+
singleton_class.attr_accessor :dump_schemas
|
314
|
+
self.dump_schemas = :schema_search_path
|
315
|
+
|
316
|
+
##
|
317
|
+
# :singleton-method:
|
318
|
+
# Show a warning when Rails couldn't parse your database.yml
|
319
|
+
# for multiple databases.
|
320
|
+
singleton_class.attr_accessor :suppress_multiple_database_warning
|
321
|
+
self.suppress_multiple_database_warning = false
|
322
|
+
|
323
|
+
##
|
324
|
+
# :singleton-method:
|
325
|
+
# If true, Rails will verify all foreign keys in the database after loading fixtures.
|
326
|
+
# An error will be raised if there are any foreign key violations, indicating incorrectly
|
327
|
+
# written fixtures.
|
328
|
+
# Supported by PostgreSQL and SQLite.
|
329
|
+
singleton_class.attr_accessor :verify_foreign_keys_for_fixtures
|
330
|
+
self.verify_foreign_keys_for_fixtures = false
|
331
|
+
|
332
|
+
singleton_class.attr_accessor :query_transformers
|
333
|
+
self.query_transformers = []
|
334
|
+
|
168
335
|
def self.eager_load!
|
169
336
|
super
|
170
337
|
ActiveRecord::Locking.eager_load!
|
@@ -172,6 +339,7 @@ module ActiveRecord
|
|
172
339
|
ActiveRecord::Associations.eager_load!
|
173
340
|
ActiveRecord::AttributeMethods.eager_load!
|
174
341
|
ActiveRecord::ConnectionAdapters.eager_load!
|
342
|
+
ActiveRecord::Encryption.eager_load!
|
175
343
|
end
|
176
344
|
end
|
177
345
|
|
@@ -27,14 +27,6 @@ module Arel # :nodoc: all
|
|
27
27
|
relation.able_to_type_cast?
|
28
28
|
end
|
29
29
|
end
|
30
|
-
|
31
|
-
class String < Attribute; end
|
32
|
-
class Time < Attribute; end
|
33
|
-
class Boolean < Attribute; end
|
34
|
-
class Decimal < Attribute; end
|
35
|
-
class Float < Attribute; end
|
36
|
-
class Integer < Attribute; end
|
37
|
-
class Undefined < Attribute; end
|
38
30
|
end
|
39
31
|
|
40
32
|
Attribute = Attributes::Attribute
|