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
|
@@ -24,9 +24,9 @@ WARNING: Rails was not able to disable referential integrity.
|
|
|
24
24
|
This is most likely caused due to missing permissions.
|
|
25
25
|
Rails needs superuser privileges to disable referential integrity.
|
|
26
26
|
|
|
27
|
-
cause: #{original_exception
|
|
27
|
+
cause: #{original_exception&.message}
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
WARNING
|
|
30
30
|
raise e
|
|
31
31
|
end
|
|
32
32
|
|
|
@@ -37,6 +37,34 @@ Rails needs superuser privileges to disable referential integrity.
|
|
|
37
37
|
rescue ActiveRecord::ActiveRecordError
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
|
+
|
|
41
|
+
def check_all_foreign_keys_valid! # :nodoc:
|
|
42
|
+
sql = <<~SQL
|
|
43
|
+
do $$
|
|
44
|
+
declare r record;
|
|
45
|
+
BEGIN
|
|
46
|
+
FOR r IN (
|
|
47
|
+
SELECT FORMAT(
|
|
48
|
+
'UPDATE pg_constraint SET convalidated=false WHERE conname = ''%I'' AND connamespace::regnamespace = ''%I''::regnamespace; ALTER TABLE %I.%I VALIDATE CONSTRAINT %I;',
|
|
49
|
+
constraint_name,
|
|
50
|
+
table_schema,
|
|
51
|
+
table_schema,
|
|
52
|
+
table_name,
|
|
53
|
+
constraint_name
|
|
54
|
+
) AS constraint_check
|
|
55
|
+
FROM information_schema.table_constraints WHERE constraint_type = 'FOREIGN KEY'
|
|
56
|
+
)
|
|
57
|
+
LOOP
|
|
58
|
+
EXECUTE (r.constraint_check);
|
|
59
|
+
END LOOP;
|
|
60
|
+
END;
|
|
61
|
+
$$;
|
|
62
|
+
SQL
|
|
63
|
+
|
|
64
|
+
transaction(requires_new: true) do
|
|
65
|
+
execute(sql)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
40
68
|
end
|
|
41
69
|
end
|
|
42
70
|
end
|
|
@@ -3,13 +3,33 @@
|
|
|
3
3
|
module ActiveRecord
|
|
4
4
|
module ConnectionAdapters
|
|
5
5
|
module PostgreSQL
|
|
6
|
-
class SchemaCreation <
|
|
6
|
+
class SchemaCreation < SchemaCreation # :nodoc:
|
|
7
7
|
private
|
|
8
|
+
delegate :quoted_include_columns_for_index, to: :@conn
|
|
9
|
+
|
|
8
10
|
def visit_AlterTable(o)
|
|
9
|
-
|
|
11
|
+
sql = super
|
|
12
|
+
sql << o.constraint_validations.map { |fk| visit_ValidateConstraint fk }.join(" ")
|
|
13
|
+
sql << o.exclusion_constraint_adds.map { |con| visit_AddExclusionConstraint con }.join(" ")
|
|
14
|
+
sql << o.exclusion_constraint_drops.map { |con| visit_DropExclusionConstraint con }.join(" ")
|
|
15
|
+
sql << o.unique_constraint_adds.map { |con| visit_AddUniqueConstraint con }.join(" ")
|
|
16
|
+
sql << o.unique_constraint_drops.map { |con| visit_DropUniqueConstraint con }.join(" ")
|
|
10
17
|
end
|
|
11
18
|
|
|
12
19
|
def visit_AddForeignKey(o)
|
|
20
|
+
super.dup.tap do |sql|
|
|
21
|
+
sql << " DEFERRABLE INITIALLY #{o.options[:deferrable].to_s.upcase}" if o.deferrable
|
|
22
|
+
sql << " NOT VALID" unless o.validate?
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def visit_ForeignKeyDefinition(o)
|
|
27
|
+
super.dup.tap do |sql|
|
|
28
|
+
sql << " DEFERRABLE INITIALLY #{o.deferrable.to_s.upcase}" if o.deferrable
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def visit_CheckConstraintDefinition(o)
|
|
13
33
|
super.dup.tap { |sql| sql << " NOT VALID" unless o.validate? }
|
|
14
34
|
end
|
|
15
35
|
|
|
@@ -17,9 +37,57 @@ module ActiveRecord
|
|
|
17
37
|
"VALIDATE CONSTRAINT #{quote_column_name(name)}"
|
|
18
38
|
end
|
|
19
39
|
|
|
40
|
+
def visit_ExclusionConstraintDefinition(o)
|
|
41
|
+
sql = ["CONSTRAINT"]
|
|
42
|
+
sql << quote_column_name(o.name)
|
|
43
|
+
sql << "EXCLUDE"
|
|
44
|
+
sql << "USING #{o.using}" if o.using
|
|
45
|
+
sql << "(#{o.expression})"
|
|
46
|
+
sql << "WHERE (#{o.where})" if o.where
|
|
47
|
+
sql << "DEFERRABLE INITIALLY #{o.deferrable.to_s.upcase}" if o.deferrable
|
|
48
|
+
|
|
49
|
+
sql.join(" ")
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def visit_UniqueConstraintDefinition(o)
|
|
53
|
+
column_name = Array(o.column).map { |column| quote_column_name(column) }.join(", ")
|
|
54
|
+
|
|
55
|
+
sql = ["CONSTRAINT"]
|
|
56
|
+
sql << quote_column_name(o.name)
|
|
57
|
+
sql << "UNIQUE"
|
|
58
|
+
|
|
59
|
+
if o.using_index
|
|
60
|
+
sql << "USING INDEX #{quote_column_name(o.using_index)}"
|
|
61
|
+
else
|
|
62
|
+
sql << "(#{column_name})"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
if o.deferrable
|
|
66
|
+
sql << "DEFERRABLE INITIALLY #{o.deferrable.to_s.upcase}"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
sql.join(" ")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def visit_AddExclusionConstraint(o)
|
|
73
|
+
"ADD #{accept(o)}"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def visit_DropExclusionConstraint(name)
|
|
77
|
+
"DROP CONSTRAINT #{quote_column_name(name)}"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def visit_AddUniqueConstraint(o)
|
|
81
|
+
"ADD #{accept(o)}"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def visit_DropUniqueConstraint(name)
|
|
85
|
+
"DROP CONSTRAINT #{quote_column_name(name)}"
|
|
86
|
+
end
|
|
87
|
+
|
|
20
88
|
def visit_ChangeColumnDefinition(o)
|
|
21
89
|
column = o.column
|
|
22
|
-
column.sql_type = type_to_sql(column.type, column.options)
|
|
90
|
+
column.sql_type = type_to_sql(column.type, **column.options)
|
|
23
91
|
quoted_column_name = quote_column_name(o.name)
|
|
24
92
|
|
|
25
93
|
change_column_sql = +"ALTER COLUMN #{quoted_column_name} TYPE #{column.sql_type}"
|
|
@@ -33,7 +101,7 @@ module ActiveRecord
|
|
|
33
101
|
if options[:using]
|
|
34
102
|
change_column_sql << " USING #{options[:using]}"
|
|
35
103
|
elsif options[:cast_as]
|
|
36
|
-
cast_as_type = type_to_sql(options[:cast_as], options)
|
|
104
|
+
cast_as_type = type_to_sql(options[:cast_as], **options)
|
|
37
105
|
change_column_sql << " USING CAST(#{quoted_column_name} AS #{cast_as_type})"
|
|
38
106
|
end
|
|
39
107
|
|
|
@@ -53,13 +121,39 @@ module ActiveRecord
|
|
|
53
121
|
change_column_sql
|
|
54
122
|
end
|
|
55
123
|
|
|
124
|
+
def visit_ChangeColumnDefaultDefinition(o)
|
|
125
|
+
sql = +"ALTER COLUMN #{quote_column_name(o.column.name)} "
|
|
126
|
+
if o.default.nil?
|
|
127
|
+
sql << "DROP DEFAULT"
|
|
128
|
+
else
|
|
129
|
+
sql << "SET DEFAULT #{quote_default_expression(o.default, o.column)}"
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
56
133
|
def add_column_options!(sql, options)
|
|
57
134
|
if options[:collation]
|
|
58
135
|
sql << " COLLATE \"#{options[:collation]}\""
|
|
59
136
|
end
|
|
137
|
+
|
|
138
|
+
if as = options[:as]
|
|
139
|
+
sql << " GENERATED ALWAYS AS (#{as})"
|
|
140
|
+
|
|
141
|
+
if options[:stored]
|
|
142
|
+
sql << " STORED"
|
|
143
|
+
else
|
|
144
|
+
raise ArgumentError, <<~MSG
|
|
145
|
+
PostgreSQL currently does not support VIRTUAL (not persisted) generated columns.
|
|
146
|
+
Specify 'stored: true' option for '#{options[:column].name}'
|
|
147
|
+
MSG
|
|
148
|
+
end
|
|
149
|
+
end
|
|
60
150
|
super
|
|
61
151
|
end
|
|
62
152
|
|
|
153
|
+
def quoted_include_columns(o)
|
|
154
|
+
String === o ? o : quoted_include_columns_for_index(o)
|
|
155
|
+
end
|
|
156
|
+
|
|
63
157
|
# Returns any SQL string to go between CREATE and TABLE. May be nil.
|
|
64
158
|
def table_modifier_in_create(o)
|
|
65
159
|
# A table cannot be both TEMPORARY and UNLOGGED, since all TEMPORARY
|
|
@@ -173,25 +173,119 @@ module ActiveRecord
|
|
|
173
173
|
# :method: xml
|
|
174
174
|
# :call-seq: xml(*names, **options)
|
|
175
175
|
|
|
176
|
+
##
|
|
177
|
+
# :method: timestamptz
|
|
178
|
+
# :call-seq: timestamptz(*names, **options)
|
|
179
|
+
|
|
180
|
+
##
|
|
181
|
+
# :method: enum
|
|
182
|
+
# :call-seq: enum(*names, **options)
|
|
183
|
+
|
|
176
184
|
included do
|
|
177
185
|
define_column_methods :bigserial, :bit, :bit_varying, :cidr, :citext, :daterange,
|
|
178
186
|
:hstore, :inet, :interval, :int4range, :int8range, :jsonb, :ltree, :macaddr,
|
|
179
187
|
:money, :numrange, :oid, :point, :line, :lseg, :box, :path, :polygon, :circle,
|
|
180
|
-
:serial, :tsrange, :tstzrange, :tsvector, :uuid, :xml
|
|
188
|
+
:serial, :tsrange, :tstzrange, :tsvector, :uuid, :xml, :timestamptz, :enum
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
ExclusionConstraintDefinition = Struct.new(:table_name, :expression, :options) do
|
|
193
|
+
def name
|
|
194
|
+
options[:name]
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def using
|
|
198
|
+
options[:using]
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def where
|
|
202
|
+
options[:where]
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def deferrable
|
|
206
|
+
options[:deferrable]
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def export_name_on_schema_dump?
|
|
210
|
+
!ActiveRecord::SchemaDumper.excl_ignore_pattern.match?(name) if name
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
UniqueConstraintDefinition = Struct.new(:table_name, :column, :options) do
|
|
215
|
+
def name
|
|
216
|
+
options[:name]
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def deferrable
|
|
220
|
+
options[:deferrable]
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def using_index
|
|
224
|
+
options[:using_index]
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def export_name_on_schema_dump?
|
|
228
|
+
!ActiveRecord::SchemaDumper.unique_ignore_pattern.match?(name) if name
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def defined_for?(name: nil, column: nil, **options)
|
|
232
|
+
options = options.slice(*self.options.keys)
|
|
233
|
+
|
|
234
|
+
(name.nil? || self.name == name.to_s) &&
|
|
235
|
+
(column.nil? || Array(self.column) == Array(column).map(&:to_s)) &&
|
|
236
|
+
options.all? { |k, v| self.options[k].to_s == v.to_s }
|
|
181
237
|
end
|
|
182
238
|
end
|
|
183
239
|
|
|
240
|
+
# = Active Record PostgreSQL Adapter \Table Definition
|
|
184
241
|
class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
|
|
185
242
|
include ColumnMethods
|
|
186
243
|
|
|
187
|
-
attr_reader :unlogged
|
|
244
|
+
attr_reader :exclusion_constraints, :unique_constraints, :unlogged
|
|
188
245
|
|
|
189
|
-
def initialize(
|
|
246
|
+
def initialize(*, **)
|
|
190
247
|
super
|
|
248
|
+
@exclusion_constraints = []
|
|
249
|
+
@unique_constraints = []
|
|
191
250
|
@unlogged = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.create_unlogged_tables
|
|
192
251
|
end
|
|
193
252
|
|
|
253
|
+
def exclusion_constraint(expression, **options)
|
|
254
|
+
exclusion_constraints << new_exclusion_constraint_definition(expression, options)
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def unique_constraint(column_name, **options)
|
|
258
|
+
unique_constraints << new_unique_constraint_definition(column_name, options)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def new_exclusion_constraint_definition(expression, options) # :nodoc:
|
|
262
|
+
options = @conn.exclusion_constraint_options(name, expression, options)
|
|
263
|
+
ExclusionConstraintDefinition.new(name, expression, options)
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def new_unique_constraint_definition(column_name, options) # :nodoc:
|
|
267
|
+
options = @conn.unique_constraint_options(name, column_name, options)
|
|
268
|
+
UniqueConstraintDefinition.new(name, column_name, options)
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def new_column_definition(name, type, **options) # :nodoc:
|
|
272
|
+
case type
|
|
273
|
+
when :virtual
|
|
274
|
+
type = options[:type]
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
super
|
|
278
|
+
end
|
|
279
|
+
|
|
194
280
|
private
|
|
281
|
+
def valid_column_definition_options
|
|
282
|
+
super + [:array, :using, :cast_as, :as, :type, :enum_type, :stored]
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def aliased_types(name, fallback)
|
|
286
|
+
fallback
|
|
287
|
+
end
|
|
288
|
+
|
|
195
289
|
def integer_like_primary_key_type(type, options)
|
|
196
290
|
if type == :bigint || options[:limit] == 8
|
|
197
291
|
:bigserial
|
|
@@ -201,21 +295,99 @@ module ActiveRecord
|
|
|
201
295
|
end
|
|
202
296
|
end
|
|
203
297
|
|
|
298
|
+
# = Active Record PostgreSQL Adapter \Table
|
|
204
299
|
class Table < ActiveRecord::ConnectionAdapters::Table
|
|
205
300
|
include ColumnMethods
|
|
301
|
+
|
|
302
|
+
# Adds an exclusion constraint.
|
|
303
|
+
#
|
|
304
|
+
# t.exclusion_constraint("price WITH =, availability_range WITH &&", using: :gist, name: "price_check")
|
|
305
|
+
#
|
|
306
|
+
# See {connection.add_exclusion_constraint}[rdoc-ref:SchemaStatements#add_exclusion_constraint]
|
|
307
|
+
def exclusion_constraint(...)
|
|
308
|
+
@base.add_exclusion_constraint(name, ...)
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
# Removes the given exclusion constraint from the table.
|
|
312
|
+
#
|
|
313
|
+
# t.remove_exclusion_constraint(name: "price_check")
|
|
314
|
+
#
|
|
315
|
+
# See {connection.remove_exclusion_constraint}[rdoc-ref:SchemaStatements#remove_exclusion_constraint]
|
|
316
|
+
def remove_exclusion_constraint(...)
|
|
317
|
+
@base.remove_exclusion_constraint(name, ...)
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
# Adds a unique constraint.
|
|
321
|
+
#
|
|
322
|
+
# t.unique_constraint(:position, name: 'unique_position', deferrable: :deferred)
|
|
323
|
+
#
|
|
324
|
+
# See {connection.add_unique_constraint}[rdoc-ref:SchemaStatements#add_unique_constraint]
|
|
325
|
+
def unique_constraint(...)
|
|
326
|
+
@base.add_unique_constraint(name, ...)
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
# Removes the given unique constraint from the table.
|
|
330
|
+
#
|
|
331
|
+
# t.remove_unique_constraint(name: "unique_position")
|
|
332
|
+
#
|
|
333
|
+
# See {connection.remove_unique_constraint}[rdoc-ref:SchemaStatements#remove_unique_constraint]
|
|
334
|
+
def remove_unique_constraint(...)
|
|
335
|
+
@base.remove_unique_constraint(name, ...)
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
# Validates the given constraint on the table.
|
|
339
|
+
#
|
|
340
|
+
# t.check_constraint("price > 0", name: "price_check", validate: false)
|
|
341
|
+
# t.validate_constraint "price_check"
|
|
342
|
+
#
|
|
343
|
+
# See {connection.validate_constraint}[rdoc-ref:SchemaStatements#validate_constraint]
|
|
344
|
+
def validate_constraint(...)
|
|
345
|
+
@base.validate_constraint(name, ...)
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# Validates the given check constraint on the table
|
|
349
|
+
#
|
|
350
|
+
# t.check_constraint("price > 0", name: "price_check", validate: false)
|
|
351
|
+
# t.validate_check_constraint name: "price_check"
|
|
352
|
+
#
|
|
353
|
+
# See {connection.validate_check_constraint}[rdoc-ref:SchemaStatements#validate_check_constraint]
|
|
354
|
+
def validate_check_constraint(...)
|
|
355
|
+
@base.validate_check_constraint(name, ...)
|
|
356
|
+
end
|
|
206
357
|
end
|
|
207
358
|
|
|
359
|
+
# = Active Record PostgreSQL Adapter Alter \Table
|
|
208
360
|
class AlterTable < ActiveRecord::ConnectionAdapters::AlterTable
|
|
209
|
-
attr_reader :constraint_validations
|
|
361
|
+
attr_reader :constraint_validations, :exclusion_constraint_adds, :exclusion_constraint_drops, :unique_constraint_adds, :unique_constraint_drops
|
|
210
362
|
|
|
211
363
|
def initialize(td)
|
|
212
364
|
super
|
|
213
365
|
@constraint_validations = []
|
|
366
|
+
@exclusion_constraint_adds = []
|
|
367
|
+
@exclusion_constraint_drops = []
|
|
368
|
+
@unique_constraint_adds = []
|
|
369
|
+
@unique_constraint_drops = []
|
|
214
370
|
end
|
|
215
371
|
|
|
216
372
|
def validate_constraint(name)
|
|
217
373
|
@constraint_validations << name
|
|
218
374
|
end
|
|
375
|
+
|
|
376
|
+
def add_exclusion_constraint(expression, options)
|
|
377
|
+
@exclusion_constraint_adds << @td.new_exclusion_constraint_definition(expression, options)
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
def drop_exclusion_constraint(constraint_name)
|
|
381
|
+
@exclusion_constraint_drops << constraint_name
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
def add_unique_constraint(column_name, options)
|
|
385
|
+
@unique_constraint_adds << @td.new_unique_constraint_definition(column_name, options)
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
def drop_unique_constraint(unique_constraint_name)
|
|
389
|
+
@unique_constraint_drops << unique_constraint_name
|
|
390
|
+
end
|
|
219
391
|
end
|
|
220
392
|
end
|
|
221
393
|
end
|
|
@@ -5,7 +5,6 @@ module ActiveRecord
|
|
|
5
5
|
module PostgreSQL
|
|
6
6
|
class SchemaDumper < ConnectionAdapters::SchemaDumper # :nodoc:
|
|
7
7
|
private
|
|
8
|
-
|
|
9
8
|
def extensions(stream)
|
|
10
9
|
extensions = @connection.extensions
|
|
11
10
|
if extensions.any?
|
|
@@ -17,9 +16,83 @@ module ActiveRecord
|
|
|
17
16
|
end
|
|
18
17
|
end
|
|
19
18
|
|
|
19
|
+
def types(stream)
|
|
20
|
+
types = @connection.enum_types
|
|
21
|
+
if types.any?
|
|
22
|
+
stream.puts " # Custom types defined in this database."
|
|
23
|
+
stream.puts " # Note that some types may not work with other database engines. Be careful if changing database."
|
|
24
|
+
types.sort.each do |name, values|
|
|
25
|
+
stream.puts " create_enum #{name.inspect}, #{values.inspect}"
|
|
26
|
+
end
|
|
27
|
+
stream.puts
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def schemas(stream)
|
|
32
|
+
schema_names = @connection.schema_names - ["public"]
|
|
33
|
+
|
|
34
|
+
if schema_names.any?
|
|
35
|
+
schema_names.sort.each do |name|
|
|
36
|
+
stream.puts " create_schema #{name.inspect}"
|
|
37
|
+
end
|
|
38
|
+
stream.puts
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def exclusion_constraints_in_create(table, stream)
|
|
43
|
+
if (exclusion_constraints = @connection.exclusion_constraints(table)).any?
|
|
44
|
+
add_exclusion_constraint_statements = exclusion_constraints.map do |exclusion_constraint|
|
|
45
|
+
parts = [
|
|
46
|
+
"t.exclusion_constraint #{exclusion_constraint.expression.inspect}"
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
parts << "where: #{exclusion_constraint.where.inspect}" if exclusion_constraint.where
|
|
50
|
+
parts << "using: #{exclusion_constraint.using.inspect}" if exclusion_constraint.using
|
|
51
|
+
parts << "deferrable: #{exclusion_constraint.deferrable.inspect}" if exclusion_constraint.deferrable
|
|
52
|
+
|
|
53
|
+
if exclusion_constraint.export_name_on_schema_dump?
|
|
54
|
+
parts << "name: #{exclusion_constraint.name.inspect}"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
" #{parts.join(', ')}"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
stream.puts add_exclusion_constraint_statements.sort.join("\n")
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def unique_constraints_in_create(table, stream)
|
|
65
|
+
if (unique_constraints = @connection.unique_constraints(table)).any?
|
|
66
|
+
add_unique_constraint_statements = unique_constraints.map do |unique_constraint|
|
|
67
|
+
parts = [
|
|
68
|
+
"t.unique_constraint #{unique_constraint.column.inspect}"
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
parts << "deferrable: #{unique_constraint.deferrable.inspect}" if unique_constraint.deferrable
|
|
72
|
+
|
|
73
|
+
if unique_constraint.export_name_on_schema_dump?
|
|
74
|
+
parts << "name: #{unique_constraint.name.inspect}"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
" #{parts.join(', ')}"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
stream.puts add_unique_constraint_statements.sort.join("\n")
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
20
84
|
def prepare_column_options(column)
|
|
21
85
|
spec = super
|
|
22
86
|
spec[:array] = "true" if column.array?
|
|
87
|
+
|
|
88
|
+
if @connection.supports_virtual_columns? && column.virtual?
|
|
89
|
+
spec[:as] = extract_expression_for_virtual_column(column)
|
|
90
|
+
spec[:stored] = true
|
|
91
|
+
spec = { type: schema_type(column).inspect }.merge!(spec)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
spec[:enum_type] = "\"#{column.sql_type}\"" if column.enum?
|
|
95
|
+
|
|
23
96
|
spec
|
|
24
97
|
end
|
|
25
98
|
|
|
@@ -44,6 +117,10 @@ module ActiveRecord
|
|
|
44
117
|
def schema_expression(column)
|
|
45
118
|
super unless column.serial?
|
|
46
119
|
end
|
|
120
|
+
|
|
121
|
+
def extract_expression_for_virtual_column(column)
|
|
122
|
+
column.default_function.inspect
|
|
123
|
+
end
|
|
47
124
|
end
|
|
48
125
|
end
|
|
49
126
|
end
|