activerecord 6.0.0 → 7.2.3
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 +996 -594
- data/MIT-LICENSE +1 -1
- data/README.rdoc +34 -34
- data/examples/performance.rb +2 -2
- data/lib/active_record/aggregations.rb +22 -20
- data/lib/active_record/association_relation.rb +22 -12
- data/lib/active_record/associations/alias_tracker.rb +41 -30
- data/lib/active_record/associations/association.rb +106 -41
- data/lib/active_record/associations/association_scope.rb +30 -21
- data/lib/active_record/associations/belongs_to_association.rb +69 -14
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +20 -6
- data/lib/active_record/associations/builder/association.rb +39 -6
- data/lib/active_record/associations/builder/belongs_to.rb +47 -17
- data/lib/active_record/associations/builder/collection_association.rb +14 -6
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -10
- data/lib/active_record/associations/builder/has_many.rb +7 -3
- data/lib/active_record/associations/builder/has_one.rb +13 -16
- data/lib/active_record/associations/builder/singular_association.rb +7 -3
- data/lib/active_record/associations/collection_association.rb +90 -53
- data/lib/active_record/associations/collection_proxy.rb +54 -19
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations/foreign_association.rb +21 -1
- data/lib/active_record/associations/has_many_association.rb +41 -10
- data/lib/active_record/associations/has_many_through_association.rb +29 -12
- data/lib/active_record/associations/has_one_association.rb +33 -9
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +41 -17
- data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
- data/lib/active_record/associations/join_dependency.rb +97 -54
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +237 -54
- data/lib/active_record/associations/preloader/batch.rb +48 -0
- data/lib/active_record/associations/preloader/branch.rb +153 -0
- data/lib/active_record/associations/preloader/through_association.rb +51 -17
- data/lib/active_record/associations/preloader.rb +55 -121
- data/lib/active_record/associations/singular_association.rb +16 -4
- data/lib/active_record/associations/through_association.rb +26 -15
- data/lib/active_record/associations.rb +454 -440
- data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
- data/lib/active_record/attribute_assignment.rb +11 -14
- data/lib/active_record/attribute_methods/before_type_cast.rb +36 -11
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/dirty.rb +75 -34
- data/lib/active_record/attribute_methods/primary_key.rb +53 -31
- data/lib/active_record/attribute_methods/query.rb +31 -22
- data/lib/active_record/attribute_methods/read.rb +16 -17
- data/lib/active_record/attribute_methods/serialization.rb +177 -35
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +18 -15
- data/lib/active_record/attribute_methods/write.rb +16 -28
- data/lib/active_record/attribute_methods.rb +227 -100
- data/lib/active_record/attributes.rb +94 -56
- data/lib/active_record/autosave_association.rb +119 -73
- data/lib/active_record/base.rb +31 -21
- data/lib/active_record/callbacks.rb +168 -55
- data/lib/active_record/coders/column_serializer.rb +61 -0
- data/lib/active_record/coders/json.rb +1 -1
- data/lib/active_record/coders/yaml_column.rb +70 -25
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +284 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +79 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +367 -565
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -57
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +277 -89
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +241 -69
- data/lib/active_record/connection_adapters/abstract/quoting.rb +122 -134
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -116
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +324 -72
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +17 -4
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +611 -211
- data/lib/active_record/connection_adapters/abstract/transaction.rb +425 -82
- data/lib/active_record/connection_adapters/abstract_adapter.rb +698 -211
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +464 -239
- data/lib/active_record/connection_adapters/column.rb +28 -1
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +32 -137
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +90 -43
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +41 -7
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +18 -1
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +13 -4
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +53 -15
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +127 -63
- data/lib/active_record/connection_adapters/pool_config.rb +83 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +57 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +54 -2
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +127 -100
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +9 -5
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +10 -2
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +15 -2
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -15
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +5 -4
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +35 -8
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.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 +30 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +23 -4
- data/lib/active_record/connection_adapters/postgresql/oid.rb +4 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +139 -106
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -2
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +98 -4
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +176 -4
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +462 -118
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -11
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +585 -295
- data/lib/active_record/connection_adapters/schema_cache.rb +399 -60
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +99 -48
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +80 -54
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +27 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +20 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +102 -24
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +425 -174
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -1
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +229 -0
- data/lib/active_record/connection_adapters.rb +176 -0
- data/lib/active_record/connection_handling.rb +243 -115
- data/lib/active_record/core.rb +481 -199
- data/lib/active_record/counter_cache.rb +69 -32
- data/lib/active_record/database_configurations/connection_url_resolver.rb +107 -0
- data/lib/active_record/database_configurations/database_config.rb +77 -10
- data/lib/active_record/database_configurations/hash_config.rb +148 -26
- data/lib/active_record/database_configurations/url_config.rb +44 -45
- data/lib/active_record/database_configurations.rb +190 -114
- data/lib/active_record/delegated_type.rb +279 -0
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +38 -0
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +5 -6
- data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
- data/lib/active_record/encryption/cipher.rb +53 -0
- data/lib/active_record/encryption/config.rb +68 -0
- data/lib/active_record/encryption/configurable.rb +60 -0
- data/lib/active_record/encryption/context.rb +42 -0
- data/lib/active_record/encryption/contexts.rb +76 -0
- data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
- data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
- data/lib/active_record/encryption/encryptable_record.rb +230 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +175 -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 +171 -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 +157 -0
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
- data/lib/active_record/encryption/key.rb +28 -0
- data/lib/active_record/encryption/key_generator.rb +53 -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_pack_message_serializer.rb +76 -0
- data/lib/active_record/encryption/message_serializer.rb +96 -0
- data/lib/active_record/encryption/null_encryptor.rb +25 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +28 -0
- data/lib/active_record/encryption/scheme.rb +100 -0
- data/lib/active_record/encryption.rb +58 -0
- data/lib/active_record/enum.rb +224 -73
- data/lib/active_record/errors.rb +254 -36
- data/lib/active_record/explain.rb +30 -17
- data/lib/active_record/explain_registry.rb +11 -6
- data/lib/active_record/explain_subscriber.rb +2 -2
- data/lib/active_record/fixture_set/file.rb +22 -15
- data/lib/active_record/fixture_set/model_metadata.rb +15 -6
- data/lib/active_record/fixture_set/render_context.rb +3 -1
- data/lib/active_record/fixture_set/table_row.rb +88 -16
- data/lib/active_record/fixture_set/table_rows.rb +4 -5
- data/lib/active_record/fixtures.rb +229 -116
- data/lib/active_record/future_result.rb +178 -0
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +121 -48
- data/lib/active_record/insert_all.rb +178 -29
- data/lib/active_record/integration.rb +16 -14
- data/lib/active_record/internal_metadata.rb +132 -21
- data/lib/active_record/legacy_yaml_adapter.rb +3 -36
- data/lib/active_record/locking/optimistic.rb +64 -33
- data/lib/active_record/locking/pessimistic.rb +21 -8
- data/lib/active_record/log_subscriber.rb +61 -30
- data/lib/active_record/marshalling.rb +59 -0
- data/lib/active_record/message_pack.rb +124 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +19 -19
- data/lib/active_record/middleware/database_selector.rb +25 -13
- data/lib/active_record/middleware/shard_selector.rb +62 -0
- data/lib/active_record/migration/command_recorder.rb +160 -55
- data/lib/active_record/migration/compatibility.rb +286 -43
- data/lib/active_record/migration/default_strategy.rb +22 -0
- data/lib/active_record/migration/execution_strategy.rb +19 -0
- data/lib/active_record/migration/join_table.rb +1 -2
- data/lib/active_record/migration/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +421 -193
- data/lib/active_record/model_schema.rb +217 -125
- data/lib/active_record/nested_attributes.rb +62 -27
- data/lib/active_record/no_touching.rb +4 -4
- data/lib/active_record/normalization.rb +163 -0
- data/lib/active_record/persistence.rb +322 -319
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +18 -15
- data/lib/active_record/query_logs.rb +193 -0
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +54 -14
- data/lib/active_record/railtie.rb +250 -72
- data/lib/active_record/railties/console_sandbox.rb +2 -4
- data/lib/active_record/railties/controller_runtime.rb +25 -11
- data/lib/active_record/railties/databases.rake +312 -197
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +45 -3
- data/lib/active_record/reflection.rb +389 -146
- data/lib/active_record/relation/batches/batch_enumerator.rb +61 -16
- data/lib/active_record/relation/batches.rb +214 -73
- data/lib/active_record/relation/calculations.rb +379 -124
- data/lib/active_record/relation/delegation.rb +36 -23
- data/lib/active_record/relation/finder_methods.rb +159 -49
- data/lib/active_record/relation/from_clause.rb +5 -1
- data/lib/active_record/relation/merger.rb +41 -33
- data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -11
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -7
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +20 -13
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
- data/lib/active_record/relation/predicate_builder.rb +79 -53
- data/lib/active_record/relation/query_attribute.rb +30 -12
- data/lib/active_record/relation/query_methods.rb +1156 -279
- data/lib/active_record/relation/record_fetch_warning.rb +12 -11
- data/lib/active_record/relation/spawn_methods.rb +10 -9
- data/lib/active_record/relation/where_clause.rb +100 -66
- data/lib/active_record/relation.rb +829 -194
- data/lib/active_record/result.rb +76 -56
- data/lib/active_record/runtime_registry.rb +71 -13
- data/lib/active_record/sanitization.rb +86 -47
- data/lib/active_record/schema.rb +39 -23
- data/lib/active_record/schema_dumper.rb +140 -33
- data/lib/active_record/schema_migration.rb +74 -29
- data/lib/active_record/scoping/default.rb +73 -19
- data/lib/active_record/scoping/named.rb +10 -28
- data/lib/active_record/scoping.rb +65 -35
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +34 -8
- data/lib/active_record/serialization.rb +11 -4
- data/lib/active_record/signed_id.rb +138 -0
- data/lib/active_record/statement_cache.rb +26 -10
- data/lib/active_record/store.rb +19 -14
- data/lib/active_record/suppressor.rb +15 -17
- data/lib/active_record/table_metadata.rb +46 -36
- data/lib/active_record/tasks/database_tasks.rb +371 -205
- data/lib/active_record/tasks/mysql_database_tasks.rb +43 -36
- data/lib/active_record/tasks/postgresql_database_tasks.rb +54 -41
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -13
- data/lib/active_record/test_databases.rb +5 -4
- data/lib/active_record/test_fixtures.rb +189 -104
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +35 -25
- data/lib/active_record/token_for.rb +123 -0
- data/lib/active_record/touch_later.rb +31 -27
- data/lib/active_record/transaction.rb +132 -0
- data/lib/active_record/transactions.rb +131 -99
- data/lib/active_record/translation.rb +3 -5
- data/lib/active_record/type/adapter_specific_registry.rb +33 -18
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -2
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/serialized.rb +11 -6
- data/lib/active_record/type/time.rb +14 -0
- data/lib/active_record/type/type_map.rb +17 -21
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type.rb +7 -2
- data/lib/active_record/type_caster/connection.rb +4 -5
- data/lib/active_record/type_caster/map.rb +8 -5
- data/lib/active_record/validations/absence.rb +1 -1
- data/lib/active_record/validations/associated.rb +13 -8
- data/lib/active_record/validations/numericality.rb +36 -0
- data/lib/active_record/validations/presence.rb +5 -28
- data/lib/active_record/validations/uniqueness.rb +88 -18
- data/lib/active_record/validations.rb +15 -8
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +446 -40
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/attributes/attribute.rb +4 -8
- data/lib/arel/collectors/bind.rb +8 -1
- data/lib/arel/collectors/composite.rb +15 -0
- data/lib/arel/collectors/sql_string.rb +7 -0
- data/lib/arel/collectors/substitute_binds.rb +7 -0
- data/lib/arel/crud.rb +30 -22
- data/lib/arel/delete_manager.rb +23 -4
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.rb +4 -0
- data/lib/arel/filter_predications.rb +9 -0
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/binary.rb +82 -9
- data/lib/arel/nodes/bind_param.rb +8 -0
- data/lib/arel/nodes/bound_sql_literal.rb +65 -0
- data/lib/arel/nodes/casted.rb +22 -10
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/delete_statement.rb +14 -13
- data/lib/arel/nodes/equality.rb +6 -9
- data/lib/arel/nodes/filter.rb +10 -0
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/function.rb +1 -0
- data/lib/arel/nodes/grouping.rb +3 -0
- data/lib/arel/nodes/homogeneous_in.rb +68 -0
- data/lib/arel/nodes/in.rb +8 -1
- data/lib/arel/nodes/infix_operation.rb +13 -1
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/join_source.rb +1 -1
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/{and.rb → nary.rb} +9 -2
- data/lib/arel/nodes/node.rb +122 -11
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/select_core.rb +2 -2
- data/lib/arel/nodes/select_statement.rb +2 -2
- data/lib/arel/nodes/sql_literal.rb +16 -0
- data/lib/arel/nodes/table_alias.rb +11 -3
- data/lib/arel/nodes/unary.rb +0 -1
- data/lib/arel/nodes/update_statement.rb +11 -4
- data/lib/arel/nodes.rb +10 -3
- data/lib/arel/predications.rb +31 -28
- data/lib/arel/select_manager.rb +18 -9
- data/lib/arel/table.rb +21 -10
- data/lib/arel/tree_manager.rb +8 -15
- data/lib/arel/update_manager.rb +25 -5
- data/lib/arel/visitors/dot.rb +94 -90
- data/lib/arel/visitors/mysql.rb +34 -6
- data/lib/arel/visitors/postgresql.rb +5 -16
- data/lib/arel/visitors/sqlite.rb +25 -1
- data/lib/arel/visitors/to_sql.rb +227 -81
- data/lib/arel/visitors/visitor.rb +2 -3
- data/lib/arel/visitors.rb +0 -7
- data/lib/arel.rb +37 -15
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +6 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -4
- data/lib/rails/generators/active_record/migration.rb +9 -3
- data/lib/rails/generators/active_record/model/USAGE +113 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +49 -4
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- 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
- data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
- data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
- metadata +117 -30
- data/lib/active_record/attribute_decorators.rb +0 -90
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -297
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
- data/lib/active_record/define_callbacks.rb +0 -22
- data/lib/active_record/null_relation.rb +0 -68
- data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
- data/lib/active_record/relation/where_clause_factory.rb +0 -33
- data/lib/arel/attributes.rb +0 -22
- data/lib/arel/visitors/depth_first.rb +0 -204
- data/lib/arel/visitors/ibm_db.rb +0 -34
- data/lib/arel/visitors/informix.rb +0 -62
- data/lib/arel/visitors/mssql.rb +0 -157
- data/lib/arel/visitors/oracle.rb +0 -159
- data/lib/arel/visitors/oracle12.rb +0 -66
- data/lib/arel/visitors/where_sql.rb +0 -23
|
@@ -4,19 +4,18 @@ 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
|
|
11
11
|
define_callbacks :commit, :rollback,
|
|
12
12
|
:before_commit,
|
|
13
|
-
:before_commit_without_transaction_enrollment,
|
|
14
|
-
:commit_without_transaction_enrollment,
|
|
15
|
-
:rollback_without_transaction_enrollment,
|
|
16
13
|
scope: [:kind, :name]
|
|
17
14
|
end
|
|
18
15
|
|
|
19
|
-
|
|
16
|
+
attr_accessor :_new_record_before_last_commit, :_last_transaction_return_status # :nodoc:
|
|
17
|
+
|
|
18
|
+
# = Active Record \Transactions
|
|
20
19
|
#
|
|
21
20
|
# \Transactions are protective blocks where SQL statements are only permanent
|
|
22
21
|
# if they can all succeed as one atomic action. The classic example is a
|
|
@@ -101,7 +100,8 @@ module ActiveRecord
|
|
|
101
100
|
# catch those in your application code.
|
|
102
101
|
#
|
|
103
102
|
# One exception is the ActiveRecord::Rollback exception, which will trigger
|
|
104
|
-
# a ROLLBACK when raised, but not be re-raised by the transaction block.
|
|
103
|
+
# a ROLLBACK when raised, but not be re-raised by the transaction block. Any
|
|
104
|
+
# other exception will be re-raised.
|
|
105
105
|
#
|
|
106
106
|
# *Warning*: one should not catch ActiveRecord::StatementInvalid exceptions
|
|
107
107
|
# inside a transaction block. ActiveRecord::StatementInvalid exceptions indicate that an
|
|
@@ -164,13 +164,13 @@ module ActiveRecord
|
|
|
164
164
|
# end
|
|
165
165
|
# end
|
|
166
166
|
#
|
|
167
|
-
# only "Kotori" is created.
|
|
167
|
+
# only "Kotori" is created.
|
|
168
168
|
#
|
|
169
169
|
# Most databases don't support true nested transactions. At the time of
|
|
170
170
|
# writing, the only database that we're aware of that supports true nested
|
|
171
171
|
# transactions, is MS-SQL. Because of this, Active Record emulates nested
|
|
172
|
-
# transactions by using savepoints
|
|
173
|
-
# https://dev.mysql.com/doc/refman/
|
|
172
|
+
# transactions by using savepoints. See
|
|
173
|
+
# https://dev.mysql.com/doc/refman/en/savepoint.html
|
|
174
174
|
# for more information about savepoints.
|
|
175
175
|
#
|
|
176
176
|
# === \Callbacks
|
|
@@ -188,6 +188,27 @@ module ActiveRecord
|
|
|
188
188
|
# #after_commit is a good spot to put in a hook to clearing a cache since clearing it from
|
|
189
189
|
# within a transaction could trigger the cache to be regenerated before the database is updated.
|
|
190
190
|
#
|
|
191
|
+
# ==== NOTE: Callbacks are deduplicated per callback by filter.
|
|
192
|
+
#
|
|
193
|
+
# Trying to define multiple callbacks with the same filter will result in a single callback being run.
|
|
194
|
+
#
|
|
195
|
+
# For example:
|
|
196
|
+
#
|
|
197
|
+
# after_commit :do_something
|
|
198
|
+
# after_commit :do_something # only the last one will be called
|
|
199
|
+
#
|
|
200
|
+
# This applies to all variations of <tt>after_*_commit</tt> callbacks as well.
|
|
201
|
+
#
|
|
202
|
+
# after_commit :do_something
|
|
203
|
+
# after_create_commit :do_something
|
|
204
|
+
# after_save_commit :do_something
|
|
205
|
+
#
|
|
206
|
+
# It is recommended to use the +on:+ option to specify when the callback should be run.
|
|
207
|
+
#
|
|
208
|
+
# after_commit :do_something, on: [:create, :update]
|
|
209
|
+
#
|
|
210
|
+
# This is equivalent to using +after_create_commit+ and +after_update_commit+, but will not be deduplicated.
|
|
211
|
+
#
|
|
191
212
|
# === Caveats
|
|
192
213
|
#
|
|
193
214
|
# If you're on MySQL, then do not use Data Definition Language (DDL) operations in nested
|
|
@@ -198,9 +219,9 @@ module ActiveRecord
|
|
|
198
219
|
# database error will occur because the savepoint has already been
|
|
199
220
|
# automatically released. The following example demonstrates the problem:
|
|
200
221
|
#
|
|
201
|
-
# Model.
|
|
202
|
-
# Model.
|
|
203
|
-
# Model.
|
|
222
|
+
# Model.lease_connection.transaction do # BEGIN
|
|
223
|
+
# Model.lease_connection.transaction(requires_new: true) do # CREATE SAVEPOINT active_record_1
|
|
224
|
+
# Model.lease_connection.create_table(...) # active_record_1 now automatically released
|
|
204
225
|
# end # RELEASE SAVEPOINT active_record_1
|
|
205
226
|
# # ^^^^ BOOM! database error!
|
|
206
227
|
# end
|
|
@@ -208,8 +229,21 @@ module ActiveRecord
|
|
|
208
229
|
# Note that "TRUNCATE" is also a MySQL DDL statement!
|
|
209
230
|
module ClassMethods
|
|
210
231
|
# See the ConnectionAdapters::DatabaseStatements#transaction API docs.
|
|
211
|
-
def transaction(options
|
|
212
|
-
connection
|
|
232
|
+
def transaction(**options, &block)
|
|
233
|
+
with_connection do |connection|
|
|
234
|
+
connection.transaction(**options, &block)
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# Returns a representation of the current transaction state,
|
|
239
|
+
# which can be a top level transaction, a savepoint, or the absence of a transaction.
|
|
240
|
+
#
|
|
241
|
+
# An object is always returned, whether or not a transaction is currently active.
|
|
242
|
+
# To check if a transaction was opened, use <tt>current_transaction.open?</tt>.
|
|
243
|
+
#
|
|
244
|
+
# See the ActiveRecord::Transaction documentation for detailed behavior.
|
|
245
|
+
def current_transaction
|
|
246
|
+
connection_pool.active_connection&.current_transaction&.user_transaction || Transaction::NULL_TRANSACTION
|
|
213
247
|
end
|
|
214
248
|
|
|
215
249
|
def before_commit(*args, &block) # :nodoc:
|
|
@@ -230,31 +264,31 @@ module ActiveRecord
|
|
|
230
264
|
# after_commit :do_bar_baz, on: [:update, :destroy]
|
|
231
265
|
#
|
|
232
266
|
def after_commit(*args, &block)
|
|
233
|
-
set_options_for_callbacks!(args)
|
|
267
|
+
set_options_for_callbacks!(args, prepend_option)
|
|
234
268
|
set_callback(:commit, :after, *args, &block)
|
|
235
269
|
end
|
|
236
270
|
|
|
237
271
|
# Shortcut for <tt>after_commit :hook, on: [ :create, :update ]</tt>.
|
|
238
272
|
def after_save_commit(*args, &block)
|
|
239
|
-
set_options_for_callbacks!(args, on: [ :create, :update ])
|
|
273
|
+
set_options_for_callbacks!(args, on: [ :create, :update ], **prepend_option)
|
|
240
274
|
set_callback(:commit, :after, *args, &block)
|
|
241
275
|
end
|
|
242
276
|
|
|
243
277
|
# Shortcut for <tt>after_commit :hook, on: :create</tt>.
|
|
244
278
|
def after_create_commit(*args, &block)
|
|
245
|
-
set_options_for_callbacks!(args, on: :create)
|
|
279
|
+
set_options_for_callbacks!(args, on: :create, **prepend_option)
|
|
246
280
|
set_callback(:commit, :after, *args, &block)
|
|
247
281
|
end
|
|
248
282
|
|
|
249
283
|
# Shortcut for <tt>after_commit :hook, on: :update</tt>.
|
|
250
284
|
def after_update_commit(*args, &block)
|
|
251
|
-
set_options_for_callbacks!(args, on: :update)
|
|
285
|
+
set_options_for_callbacks!(args, on: :update, **prepend_option)
|
|
252
286
|
set_callback(:commit, :after, *args, &block)
|
|
253
287
|
end
|
|
254
288
|
|
|
255
289
|
# Shortcut for <tt>after_commit :hook, on: :destroy</tt>.
|
|
256
290
|
def after_destroy_commit(*args, &block)
|
|
257
|
-
set_options_for_callbacks!(args, on: :destroy)
|
|
291
|
+
set_options_for_callbacks!(args, on: :destroy, **prepend_option)
|
|
258
292
|
set_callback(:commit, :after, *args, &block)
|
|
259
293
|
end
|
|
260
294
|
|
|
@@ -262,26 +296,37 @@ module ActiveRecord
|
|
|
262
296
|
#
|
|
263
297
|
# Please check the documentation of #after_commit for options.
|
|
264
298
|
def after_rollback(*args, &block)
|
|
265
|
-
set_options_for_callbacks!(args)
|
|
299
|
+
set_options_for_callbacks!(args, prepend_option)
|
|
266
300
|
set_callback(:rollback, :after, *args, &block)
|
|
267
301
|
end
|
|
268
302
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
303
|
+
# Similar to ActiveSupport::Callbacks::ClassMethods#set_callback, but with
|
|
304
|
+
# support for options available on #after_commit and #after_rollback callbacks.
|
|
305
|
+
def set_callback(name, *filter_list, &block)
|
|
306
|
+
options = filter_list.extract_options!
|
|
307
|
+
filter_list << options
|
|
308
|
+
|
|
309
|
+
if name.in?([:commit, :rollback]) && options[:on]
|
|
310
|
+
fire_on = Array(options[:on])
|
|
311
|
+
assert_valid_transaction_action(fire_on)
|
|
312
|
+
options[:if] = [
|
|
313
|
+
-> { transaction_include_any_action?(fire_on) },
|
|
314
|
+
*options[:if]
|
|
315
|
+
]
|
|
316
|
+
end
|
|
273
317
|
|
|
274
|
-
def after_commit_without_transaction_enrollment(*args, &block) # :nodoc:
|
|
275
|
-
set_options_for_callbacks!(args)
|
|
276
|
-
set_callback(:commit_without_transaction_enrollment, :after, *args, &block)
|
|
277
|
-
end
|
|
278
318
|
|
|
279
|
-
|
|
280
|
-
set_options_for_callbacks!(args)
|
|
281
|
-
set_callback(:rollback_without_transaction_enrollment, :after, *args, &block)
|
|
319
|
+
super(name, *filter_list, &block)
|
|
282
320
|
end
|
|
283
321
|
|
|
284
322
|
private
|
|
323
|
+
def prepend_option
|
|
324
|
+
if ActiveRecord.run_after_transaction_callbacks_in_order_defined
|
|
325
|
+
{ prepend: true }
|
|
326
|
+
else
|
|
327
|
+
{}
|
|
328
|
+
end
|
|
329
|
+
end
|
|
285
330
|
|
|
286
331
|
def set_options_for_callbacks!(args, enforced_options = {})
|
|
287
332
|
options = args.extract_options!.merge!(enforced_options)
|
|
@@ -290,8 +335,10 @@ module ActiveRecord
|
|
|
290
335
|
if options[:on]
|
|
291
336
|
fire_on = Array(options[:on])
|
|
292
337
|
assert_valid_transaction_action(fire_on)
|
|
293
|
-
options[:if] =
|
|
294
|
-
|
|
338
|
+
options[:if] = [
|
|
339
|
+
-> { transaction_include_any_action?(fire_on) },
|
|
340
|
+
*options[:if]
|
|
341
|
+
]
|
|
295
342
|
end
|
|
296
343
|
end
|
|
297
344
|
|
|
@@ -303,28 +350,27 @@ module ActiveRecord
|
|
|
303
350
|
end
|
|
304
351
|
|
|
305
352
|
# See ActiveRecord::Transactions::ClassMethods for detailed documentation.
|
|
306
|
-
def transaction(options
|
|
307
|
-
self.class.transaction(options, &block)
|
|
353
|
+
def transaction(**options, &block)
|
|
354
|
+
self.class.transaction(**options, &block)
|
|
308
355
|
end
|
|
309
356
|
|
|
310
|
-
def destroy
|
|
357
|
+
def destroy # :nodoc:
|
|
311
358
|
with_transaction_returning_status { super }
|
|
312
359
|
end
|
|
313
360
|
|
|
314
|
-
def save(
|
|
361
|
+
def save(**) # :nodoc:
|
|
315
362
|
with_transaction_returning_status { super }
|
|
316
363
|
end
|
|
317
364
|
|
|
318
|
-
def save!(
|
|
365
|
+
def save!(**) # :nodoc:
|
|
319
366
|
with_transaction_returning_status { super }
|
|
320
367
|
end
|
|
321
368
|
|
|
322
|
-
def touch(
|
|
369
|
+
def touch(*, **) # :nodoc:
|
|
323
370
|
with_transaction_returning_status { super }
|
|
324
371
|
end
|
|
325
372
|
|
|
326
373
|
def before_committed! # :nodoc:
|
|
327
|
-
_run_before_commit_without_transaction_enrollment_callbacks
|
|
328
374
|
_run_before_commit_callbacks
|
|
329
375
|
end
|
|
330
376
|
|
|
@@ -332,50 +378,49 @@ module ActiveRecord
|
|
|
332
378
|
#
|
|
333
379
|
# Ensure that it is not called if the object was never persisted (failed create),
|
|
334
380
|
# but call it after the commit of a destroyed object.
|
|
335
|
-
def committed!(should_run_callbacks: true)
|
|
381
|
+
def committed!(should_run_callbacks: true) # :nodoc:
|
|
382
|
+
@_start_transaction_state = nil
|
|
336
383
|
if should_run_callbacks
|
|
337
384
|
@_committed_already_called = true
|
|
338
|
-
_run_commit_without_transaction_enrollment_callbacks
|
|
339
385
|
_run_commit_callbacks
|
|
340
386
|
end
|
|
341
387
|
ensure
|
|
342
|
-
@_committed_already_called = false
|
|
343
|
-
force_clear_transaction_record_state
|
|
388
|
+
@_committed_already_called = @_trigger_update_callback = @_trigger_destroy_callback = false
|
|
344
389
|
end
|
|
345
390
|
|
|
346
391
|
# Call the #after_rollback callbacks. The +force_restore_state+ argument indicates if the record
|
|
347
392
|
# state should be rolled back to the beginning or just to the last savepoint.
|
|
348
|
-
def rolledback!(force_restore_state: false, should_run_callbacks: true)
|
|
393
|
+
def rolledback!(force_restore_state: false, should_run_callbacks: true) # :nodoc:
|
|
349
394
|
if should_run_callbacks
|
|
350
395
|
_run_rollback_callbacks
|
|
351
|
-
_run_rollback_without_transaction_enrollment_callbacks
|
|
352
396
|
end
|
|
353
397
|
ensure
|
|
354
398
|
restore_transaction_record_state(force_restore_state)
|
|
355
399
|
clear_transaction_record_state
|
|
400
|
+
@_trigger_update_callback = @_trigger_destroy_callback = false if force_restore_state
|
|
356
401
|
end
|
|
357
402
|
|
|
358
|
-
# Executes
|
|
359
|
-
# status flag. If the status is true the transaction is committed,
|
|
360
|
-
# a ROLLBACK is issued. In any case the status flag is returned.
|
|
403
|
+
# Executes a block within a transaction and captures its return value as a
|
|
404
|
+
# status flag. If the status is true, the transaction is committed,
|
|
405
|
+
# otherwise a ROLLBACK is issued. In any case, the status flag is returned.
|
|
361
406
|
#
|
|
362
407
|
# This method is available within the context of an ActiveRecord::Base
|
|
363
408
|
# instance.
|
|
364
409
|
def with_transaction_returning_status
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
add_to_transaction
|
|
369
|
-
else
|
|
370
|
-
sync_with_transaction_state if @transaction_state&.finalized?
|
|
371
|
-
@transaction_state = self.class.connection.transaction_state
|
|
372
|
-
end
|
|
373
|
-
remember_transaction_record_state
|
|
410
|
+
self.class.with_connection do |connection|
|
|
411
|
+
status = nil
|
|
412
|
+
ensure_finalize = !connection.transaction_open?
|
|
374
413
|
|
|
375
|
-
|
|
376
|
-
|
|
414
|
+
connection.transaction do
|
|
415
|
+
add_to_transaction(ensure_finalize || has_transactional_callbacks?)
|
|
416
|
+
remember_transaction_record_state
|
|
417
|
+
|
|
418
|
+
status = yield
|
|
419
|
+
raise ActiveRecord::Rollback unless status
|
|
420
|
+
end
|
|
421
|
+
@_last_transaction_return_status = status
|
|
422
|
+
status
|
|
377
423
|
end
|
|
378
|
-
status
|
|
379
424
|
end
|
|
380
425
|
|
|
381
426
|
def trigger_transactional_callbacks? # :nodoc:
|
|
@@ -386,11 +431,20 @@ module ActiveRecord
|
|
|
386
431
|
private
|
|
387
432
|
attr_reader :_committed_already_called, :_trigger_update_callback, :_trigger_destroy_callback
|
|
388
433
|
|
|
434
|
+
def init_internals
|
|
435
|
+
super
|
|
436
|
+
@_start_transaction_state = nil
|
|
437
|
+
@_last_transaction_return_status = nil
|
|
438
|
+
@_committed_already_called = nil
|
|
439
|
+
@_new_record_before_last_commit = nil
|
|
440
|
+
end
|
|
441
|
+
|
|
389
442
|
# Save the new record state and id of a record so it can be restored later if a transaction fails.
|
|
390
443
|
def remember_transaction_record_state
|
|
391
444
|
@_start_transaction_state ||= {
|
|
392
445
|
id: id,
|
|
393
446
|
new_record: @new_record,
|
|
447
|
+
previously_new_record: @previously_new_record,
|
|
394
448
|
destroyed: @destroyed,
|
|
395
449
|
attributes: @attributes,
|
|
396
450
|
frozen?: frozen?,
|
|
@@ -409,13 +463,7 @@ module ActiveRecord
|
|
|
409
463
|
def clear_transaction_record_state
|
|
410
464
|
return unless @_start_transaction_state
|
|
411
465
|
@_start_transaction_state[:level] -= 1
|
|
412
|
-
|
|
413
|
-
end
|
|
414
|
-
|
|
415
|
-
# Force to clear the transaction record state.
|
|
416
|
-
def force_clear_transaction_record_state
|
|
417
|
-
@_start_transaction_state = nil
|
|
418
|
-
@transaction_state = nil
|
|
466
|
+
@_start_transaction_state = nil if @_start_transaction_state[:level] < 1
|
|
419
467
|
end
|
|
420
468
|
|
|
421
469
|
# Restore the new record state and id of a record that was previously saved by a call to save_record_state.
|
|
@@ -423,6 +471,7 @@ module ActiveRecord
|
|
|
423
471
|
if restore_state = @_start_transaction_state
|
|
424
472
|
if force_restore_state || restore_state[:level] <= 1
|
|
425
473
|
@new_record = restore_state[:new_record]
|
|
474
|
+
@previously_new_record = restore_state[:previously_new_record]
|
|
426
475
|
@destroyed = restore_state[:destroyed]
|
|
427
476
|
@attributes = restore_state[:attributes].map do |attr|
|
|
428
477
|
value = @attributes.fetch_value(attr.name)
|
|
@@ -431,8 +480,16 @@ module ActiveRecord
|
|
|
431
480
|
end
|
|
432
481
|
@mutations_from_database = nil
|
|
433
482
|
@mutations_before_last_save = nil
|
|
434
|
-
if
|
|
435
|
-
|
|
483
|
+
if self.class.composite_primary_key?
|
|
484
|
+
if restore_state[:id] != @primary_key.map { |col| @attributes.fetch_value(col) }
|
|
485
|
+
@primary_key.zip(restore_state[:id]).each do |col, val|
|
|
486
|
+
@attributes.write_from_user(col, val)
|
|
487
|
+
end
|
|
488
|
+
end
|
|
489
|
+
else
|
|
490
|
+
if @attributes.fetch_value(@primary_key) != restore_state[:id]
|
|
491
|
+
@attributes.write_from_user(@primary_key, restore_state[:id])
|
|
492
|
+
end
|
|
436
493
|
end
|
|
437
494
|
freeze if restore_state[:frozen?]
|
|
438
495
|
end
|
|
@@ -455,39 +512,14 @@ module ActiveRecord
|
|
|
455
512
|
|
|
456
513
|
# Add the record to the current transaction so that the #after_rollback and #after_commit
|
|
457
514
|
# callbacks can be called.
|
|
458
|
-
def add_to_transaction
|
|
459
|
-
self.class.connection
|
|
515
|
+
def add_to_transaction(ensure_finalize = true)
|
|
516
|
+
self.class.with_connection do |connection|
|
|
517
|
+
connection.add_transaction_record(self, ensure_finalize)
|
|
518
|
+
end
|
|
460
519
|
end
|
|
461
520
|
|
|
462
521
|
def has_transactional_callbacks?
|
|
463
522
|
!_rollback_callbacks.empty? || !_commit_callbacks.empty? || !_before_commit_callbacks.empty?
|
|
464
523
|
end
|
|
465
|
-
|
|
466
|
-
# Updates the attributes on this particular Active Record object so that
|
|
467
|
-
# if it's associated with a transaction, then the state of the Active Record
|
|
468
|
-
# object will be updated to reflect the current state of the transaction.
|
|
469
|
-
#
|
|
470
|
-
# The <tt>@transaction_state</tt> variable stores the states of the associated
|
|
471
|
-
# transaction. This relies on the fact that a transaction can only be in
|
|
472
|
-
# one rollback or commit (otherwise a list of states would be required).
|
|
473
|
-
# Each Active Record object inside of a transaction carries that transaction's
|
|
474
|
-
# TransactionState.
|
|
475
|
-
#
|
|
476
|
-
# This method checks to see if the ActiveRecord object's state reflects
|
|
477
|
-
# the TransactionState, and rolls back or commits the Active Record object
|
|
478
|
-
# as appropriate.
|
|
479
|
-
def sync_with_transaction_state
|
|
480
|
-
if transaction_state = @transaction_state
|
|
481
|
-
if transaction_state.fully_committed?
|
|
482
|
-
force_clear_transaction_record_state
|
|
483
|
-
elsif transaction_state.committed?
|
|
484
|
-
clear_transaction_record_state
|
|
485
|
-
elsif transaction_state.rolledback?
|
|
486
|
-
force_restore_state = transaction_state.fully_rolledback?
|
|
487
|
-
restore_transaction_record_state(force_restore_state)
|
|
488
|
-
clear_transaction_record_state
|
|
489
|
-
end
|
|
490
|
-
end
|
|
491
|
-
end
|
|
492
524
|
end
|
|
493
525
|
end
|
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module ActiveRecord
|
|
4
4
|
module Translation
|
|
5
|
-
include ActiveModel::Translation
|
|
6
|
-
|
|
7
5
|
# Set the lookup ancestors for ActiveModel.
|
|
8
|
-
def lookup_ancestors
|
|
6
|
+
def lookup_ancestors # :nodoc:
|
|
9
7
|
klass = self
|
|
10
8
|
classes = [klass]
|
|
11
9
|
return classes if klass == ActiveRecord::Base
|
|
@@ -16,8 +14,8 @@ module ActiveRecord
|
|
|
16
14
|
classes
|
|
17
15
|
end
|
|
18
16
|
|
|
19
|
-
# Set the i18n scope to
|
|
20
|
-
def i18n_scope
|
|
17
|
+
# Set the i18n scope to override ActiveModel.
|
|
18
|
+
def i18n_scope # :nodoc:
|
|
21
19
|
:activerecord
|
|
22
20
|
end
|
|
23
21
|
end
|
|
@@ -1,29 +1,50 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "active_model/type/registry"
|
|
4
|
-
|
|
5
3
|
module ActiveRecord
|
|
6
4
|
# :stopdoc:
|
|
7
5
|
module Type
|
|
8
|
-
class AdapterSpecificRegistry
|
|
6
|
+
class AdapterSpecificRegistry # :nodoc:
|
|
7
|
+
def initialize
|
|
8
|
+
@registrations = []
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def initialize_copy(other)
|
|
12
|
+
@registrations = @registrations.dup
|
|
13
|
+
end
|
|
14
|
+
|
|
9
15
|
def add_modifier(options, klass, **args)
|
|
10
16
|
registrations << DecorationRegistration.new(options, klass, **args)
|
|
11
17
|
end
|
|
12
18
|
|
|
13
|
-
|
|
19
|
+
def register(type_name, klass = nil, **options, &block)
|
|
20
|
+
unless block_given?
|
|
21
|
+
block = proc { |_, *args| klass.new(*args) }
|
|
22
|
+
block.ruby2_keywords if block.respond_to?(:ruby2_keywords)
|
|
23
|
+
end
|
|
24
|
+
registrations << Registration.new(type_name, block, **options)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def lookup(symbol, *args, **kwargs)
|
|
28
|
+
registration = find_registration(symbol, *args, **kwargs)
|
|
14
29
|
|
|
15
|
-
|
|
16
|
-
|
|
30
|
+
if registration
|
|
31
|
+
registration.call(self, symbol, *args, **kwargs)
|
|
32
|
+
else
|
|
33
|
+
raise ArgumentError, "Unknown type #{symbol.inspect}"
|
|
17
34
|
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
attr_reader :registrations
|
|
18
39
|
|
|
19
|
-
def find_registration(symbol, *args)
|
|
40
|
+
def find_registration(symbol, *args, **kwargs)
|
|
20
41
|
registrations
|
|
21
|
-
.select { |registration| registration.matches?(symbol, *args) }
|
|
42
|
+
.select { |registration| registration.matches?(symbol, *args, **kwargs) }
|
|
22
43
|
.max
|
|
23
44
|
end
|
|
24
45
|
end
|
|
25
46
|
|
|
26
|
-
class Registration
|
|
47
|
+
class Registration # :nodoc:
|
|
27
48
|
def initialize(name, block, adapter: nil, override: nil)
|
|
28
49
|
@name = name
|
|
29
50
|
@block = block
|
|
@@ -32,11 +53,7 @@ module ActiveRecord
|
|
|
32
53
|
end
|
|
33
54
|
|
|
34
55
|
def call(_registry, *args, adapter: nil, **kwargs)
|
|
35
|
-
|
|
36
|
-
block.call(*args, **kwargs)
|
|
37
|
-
else
|
|
38
|
-
block.call(*args)
|
|
39
|
-
end
|
|
56
|
+
block.call(*args, **kwargs)
|
|
40
57
|
end
|
|
41
58
|
|
|
42
59
|
def matches?(type_name, *args, **kwargs)
|
|
@@ -53,7 +70,6 @@ module ActiveRecord
|
|
|
53
70
|
end
|
|
54
71
|
|
|
55
72
|
protected
|
|
56
|
-
|
|
57
73
|
attr_reader :name, :block, :adapter, :override
|
|
58
74
|
|
|
59
75
|
def priority
|
|
@@ -72,7 +88,6 @@ module ActiveRecord
|
|
|
72
88
|
end
|
|
73
89
|
|
|
74
90
|
private
|
|
75
|
-
|
|
76
91
|
def matches_adapter?(adapter: nil, **)
|
|
77
92
|
(self.adapter.nil? || adapter == self.adapter)
|
|
78
93
|
end
|
|
@@ -92,7 +107,7 @@ module ActiveRecord
|
|
|
92
107
|
end
|
|
93
108
|
end
|
|
94
109
|
|
|
95
|
-
class DecorationRegistration < Registration
|
|
110
|
+
class DecorationRegistration < Registration # :nodoc:
|
|
96
111
|
def initialize(options, klass, adapter: nil)
|
|
97
112
|
@options = options
|
|
98
113
|
@klass = klass
|
|
@@ -123,7 +138,7 @@ module ActiveRecord
|
|
|
123
138
|
end
|
|
124
139
|
end
|
|
125
140
|
|
|
126
|
-
class TypeConflictError < StandardError
|
|
141
|
+
class TypeConflictError < StandardError # :nodoc:
|
|
127
142
|
end
|
|
128
143
|
# :startdoc:
|
|
129
144
|
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
|
|
@@ -16,7 +49,6 @@ module ActiveRecord
|
|
|
16
49
|
end
|
|
17
50
|
|
|
18
51
|
private
|
|
19
|
-
|
|
20
52
|
def perform_fetch(type, *args, &block)
|
|
21
53
|
@mapping.fetch(type, block).call(type, *args)
|
|
22
54
|
end
|
|
@@ -4,12 +4,17 @@ module ActiveRecord
|
|
|
4
4
|
module Type
|
|
5
5
|
module Internal
|
|
6
6
|
module Timezone
|
|
7
|
+
def initialize(timezone: nil, **kwargs)
|
|
8
|
+
super(**kwargs)
|
|
9
|
+
@timezone = timezone
|
|
10
|
+
end
|
|
11
|
+
|
|
7
12
|
def is_utc?
|
|
8
|
-
|
|
13
|
+
default_timezone == :utc
|
|
9
14
|
end
|
|
10
15
|
|
|
11
16
|
def default_timezone
|
|
12
|
-
ActiveRecord
|
|
17
|
+
@timezone || ActiveRecord.default_timezone
|
|
13
18
|
end
|
|
14
19
|
end
|
|
15
20
|
end
|
|
@@ -30,9 +30,7 @@ module ActiveRecord
|
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
Kernel.instance_method(:inspect).bind(self).call
|
|
35
|
-
end
|
|
33
|
+
define_method(:inspect, Kernel.instance_method(:inspect))
|
|
36
34
|
|
|
37
35
|
def changed_in_place?(raw_old_value, value)
|
|
38
36
|
return false if value.nil?
|
|
@@ -55,15 +53,22 @@ module ActiveRecord
|
|
|
55
53
|
coder.respond_to?(:object_class) && value.is_a?(coder.object_class)
|
|
56
54
|
end
|
|
57
55
|
|
|
58
|
-
|
|
56
|
+
def serialized? # :nodoc:
|
|
57
|
+
true
|
|
58
|
+
end
|
|
59
59
|
|
|
60
|
+
private
|
|
60
61
|
def default_value?(value)
|
|
61
62
|
value == coder.load(nil)
|
|
62
63
|
end
|
|
63
64
|
|
|
64
65
|
def encoded(value)
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
return if default_value?(value)
|
|
67
|
+
payload = coder.dump(value)
|
|
68
|
+
if payload && @subtype.binary?
|
|
69
|
+
ActiveModel::Type::Binary::Data.new(payload)
|
|
70
|
+
else
|
|
71
|
+
payload
|
|
67
72
|
end
|
|
68
73
|
end
|
|
69
74
|
end
|
|
@@ -16,6 +16,20 @@ module ActiveRecord
|
|
|
16
16
|
value
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
|
+
|
|
20
|
+
def serialize_cast_value(value) # :nodoc:
|
|
21
|
+
Value.new(super) if value
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
def cast_value(value)
|
|
26
|
+
case value = super
|
|
27
|
+
when Value
|
|
28
|
+
value.__getobj__
|
|
29
|
+
else
|
|
30
|
+
value
|
|
31
|
+
end
|
|
32
|
+
end
|
|
19
33
|
end
|
|
20
34
|
end
|
|
21
35
|
end
|