activerecord 6.1.7 → 7.2.0
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 +520 -1385
- data/MIT-LICENSE +1 -1
- data/README.rdoc +31 -31
- data/examples/performance.rb +2 -2
- data/lib/active_record/aggregations.rb +17 -14
- data/lib/active_record/association_relation.rb +2 -12
- data/lib/active_record/associations/alias_tracker.rb +25 -19
- data/lib/active_record/associations/association.rb +60 -21
- data/lib/active_record/associations/association_scope.rb +17 -12
- data/lib/active_record/associations/belongs_to_association.rb +37 -11
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -4
- data/lib/active_record/associations/builder/association.rb +11 -5
- data/lib/active_record/associations/builder/belongs_to.rb +41 -14
- data/lib/active_record/associations/builder/collection_association.rb +10 -3
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -7
- data/lib/active_record/associations/builder/has_many.rb +4 -4
- data/lib/active_record/associations/builder/has_one.rb +4 -4
- data/lib/active_record/associations/builder/singular_association.rb +6 -2
- data/lib/active_record/associations/collection_association.rb +46 -36
- data/lib/active_record/associations/collection_proxy.rb +44 -16
- 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 +10 -3
- data/lib/active_record/associations/has_many_association.rb +29 -19
- data/lib/active_record/associations/has_many_through_association.rb +12 -7
- data/lib/active_record/associations/has_one_association.rb +20 -10
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +27 -25
- data/lib/active_record/associations/join_dependency.rb +23 -15
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +212 -53
- 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 +50 -16
- data/lib/active_record/associations/preloader.rb +50 -121
- data/lib/active_record/associations/singular_association.rb +15 -3
- data/lib/active_record/associations/through_association.rb +25 -14
- data/lib/active_record/associations.rb +404 -509
- data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
- data/lib/active_record/attribute_assignment.rb +2 -14
- data/lib/active_record/attribute_methods/before_type_cast.rb +24 -2
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/dirty.rb +73 -22
- data/lib/active_record/attribute_methods/primary_key.rb +47 -27
- data/lib/active_record/attribute_methods/query.rb +31 -19
- data/lib/active_record/attribute_methods/read.rb +14 -11
- data/lib/active_record/attribute_methods/serialization.rb +174 -37
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +11 -9
- data/lib/active_record/attribute_methods/write.rb +12 -15
- data/lib/active_record/attribute_methods.rb +164 -52
- data/lib/active_record/attributes.rb +51 -49
- data/lib/active_record/autosave_association.rb +74 -57
- data/lib/active_record/base.rb +27 -5
- data/lib/active_record/callbacks.rb +18 -34
- 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 -46
- 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 +327 -612
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -17
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +199 -60
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +201 -64
- data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -131
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +21 -20
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +186 -31
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +377 -142
- data/lib/active_record/connection_adapters/abstract/transaction.rb +361 -76
- data/lib/active_record/connection_adapters/abstract_adapter.rb +624 -163
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +345 -166
- data/lib/active_record/connection_adapters/column.rb +13 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +29 -130
- data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -55
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +45 -14
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +107 -68
- data/lib/active_record/connection_adapters/pool_config.rb +26 -16
- data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +114 -54
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +12 -3
- 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 +14 -4
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +137 -104
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +92 -2
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +173 -3
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +401 -77
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +518 -251
- data/lib/active_record/connection_adapters/schema_cache.rb +326 -102
- data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +78 -55
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +68 -54
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
- 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 +66 -22
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +372 -130
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
- 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 +130 -6
- data/lib/active_record/connection_handling.rb +132 -146
- data/lib/active_record/core.rb +276 -251
- data/lib/active_record/counter_cache.rb +68 -34
- data/lib/active_record/database_configurations/connection_url_resolver.rb +9 -3
- data/lib/active_record/database_configurations/database_config.rb +34 -10
- data/lib/active_record/database_configurations/hash_config.rb +107 -31
- data/lib/active_record/database_configurations/url_config.rb +38 -13
- data/lib/active_record/database_configurations.rb +96 -60
- data/lib/active_record/delegated_type.rb +90 -20
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +4 -2
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +3 -3
- 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 +170 -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 +56 -0
- data/lib/active_record/enum.rb +163 -63
- data/lib/active_record/errors.rb +210 -27
- data/lib/active_record/explain.rb +21 -12
- data/lib/active_record/explain_registry.rb +11 -6
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +15 -1
- data/lib/active_record/fixture_set/model_metadata.rb +14 -4
- data/lib/active_record/fixture_set/render_context.rb +2 -0
- data/lib/active_record/fixture_set/table_row.rb +70 -14
- data/lib/active_record/fixture_set/table_rows.rb +4 -4
- data/lib/active_record/fixtures.rb +179 -112
- data/lib/active_record/future_result.rb +178 -0
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +85 -31
- data/lib/active_record/insert_all.rb +148 -32
- data/lib/active_record/integration.rb +14 -10
- data/lib/active_record/internal_metadata.rb +123 -23
- data/lib/active_record/legacy_yaml_adapter.rb +2 -39
- data/lib/active_record/locking/optimistic.rb +43 -27
- data/lib/active_record/locking/pessimistic.rb +15 -6
- data/lib/active_record/log_subscriber.rb +41 -29
- data/lib/active_record/marshalling.rb +56 -0
- data/lib/active_record/message_pack.rb +124 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +10 -10
- data/lib/active_record/middleware/database_selector.rb +23 -13
- data/lib/active_record/middleware/shard_selector.rb +62 -0
- data/lib/active_record/migration/command_recorder.rb +113 -16
- data/lib/active_record/migration/compatibility.rb +235 -46
- 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 -1
- data/lib/active_record/migration/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +374 -177
- data/lib/active_record/model_schema.rb +143 -159
- data/lib/active_record/nested_attributes.rb +48 -21
- data/lib/active_record/no_touching.rb +3 -3
- data/lib/active_record/normalization.rb +163 -0
- data/lib/active_record/persistence.rb +282 -283
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +19 -25
- data/lib/active_record/query_logs.rb +189 -0
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +44 -9
- data/lib/active_record/railtie.rb +234 -71
- data/lib/active_record/railties/controller_runtime.rb +25 -11
- data/lib/active_record/railties/databases.rake +189 -256
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +41 -3
- data/lib/active_record/reflection.rb +325 -103
- data/lib/active_record/relation/batches/batch_enumerator.rb +38 -9
- data/lib/active_record/relation/batches.rb +198 -63
- data/lib/active_record/relation/calculations.rb +300 -111
- data/lib/active_record/relation/delegation.rb +33 -22
- data/lib/active_record/relation/finder_methods.rb +123 -52
- data/lib/active_record/relation/merger.rb +26 -19
- data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +38 -4
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -7
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
- data/lib/active_record/relation/predicate_builder.rb +29 -22
- data/lib/active_record/relation/query_attribute.rb +30 -12
- data/lib/active_record/relation/query_methods.rb +842 -150
- data/lib/active_record/relation/record_fetch_warning.rb +10 -9
- data/lib/active_record/relation/spawn_methods.rb +7 -6
- data/lib/active_record/relation/where_clause.rb +15 -36
- data/lib/active_record/relation.rb +736 -145
- data/lib/active_record/result.rb +67 -54
- data/lib/active_record/runtime_registry.rb +71 -13
- data/lib/active_record/sanitization.rb +84 -34
- data/lib/active_record/schema.rb +39 -23
- data/lib/active_record/schema_dumper.rb +90 -31
- data/lib/active_record/schema_migration.rb +74 -23
- data/lib/active_record/scoping/default.rb +72 -15
- data/lib/active_record/scoping/named.rb +5 -13
- data/lib/active_record/scoping.rb +65 -34
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +21 -3
- data/lib/active_record/serialization.rb +6 -1
- data/lib/active_record/signed_id.rb +30 -9
- data/lib/active_record/statement_cache.rb +7 -7
- data/lib/active_record/store.rb +10 -10
- data/lib/active_record/suppressor.rb +13 -15
- data/lib/active_record/table_metadata.rb +7 -3
- data/lib/active_record/tasks/database_tasks.rb +277 -149
- data/lib/active_record/tasks/mysql_database_tasks.rb +16 -7
- data/lib/active_record/tasks/postgresql_database_tasks.rb +35 -26
- data/lib/active_record/tasks/sqlite_database_tasks.rb +16 -7
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +173 -155
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +32 -19
- data/lib/active_record/token_for.rb +123 -0
- data/lib/active_record/touch_later.rb +12 -7
- data/lib/active_record/transaction.rb +132 -0
- data/lib/active_record/transactions.rb +118 -41
- data/lib/active_record/translation.rb +3 -5
- data/lib/active_record/type/adapter_specific_registry.rb +32 -14
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/serialized.rb +9 -7
- data/lib/active_record/type/time.rb +4 -0
- data/lib/active_record/type/type_map.rb +17 -20
- data/lib/active_record/type.rb +1 -2
- data/lib/active_record/type_caster/connection.rb +4 -4
- data/lib/active_record/validations/absence.rb +1 -1
- data/lib/active_record/validations/associated.rb +13 -7
- data/lib/active_record/validations/numericality.rb +5 -4
- data/lib/active_record/validations/presence.rb +5 -28
- data/lib/active_record/validations/uniqueness.rb +64 -15
- data/lib/active_record/validations.rb +12 -5
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +444 -32
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/attributes/attribute.rb +0 -8
- data/lib/arel/collectors/bind.rb +2 -0
- data/lib/arel/collectors/composite.rb +7 -0
- data/lib/arel/collectors/sql_string.rb +1 -1
- data/lib/arel/collectors/substitute_binds.rb +1 -1
- data/lib/arel/crud.rb +28 -22
- data/lib/arel/delete_manager.rb +18 -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 +6 -7
- data/lib/arel/nodes/bound_sql_literal.rb +65 -0
- data/lib/arel/nodes/casted.rb +1 -1
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/delete_statement.rb +12 -13
- 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/homogeneous_in.rb +1 -9
- data/lib/arel/nodes/insert_statement.rb +2 -2
- 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 +115 -5
- 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 +13 -0
- data/lib/arel/nodes/table_alias.rb +4 -0
- data/lib/arel/nodes/update_statement.rb +8 -3
- data/lib/arel/nodes.rb +7 -2
- data/lib/arel/predications.rb +14 -4
- data/lib/arel/select_manager.rb +11 -5
- data/lib/arel/table.rb +9 -6
- data/lib/arel/tree_manager.rb +8 -15
- data/lib/arel/update_manager.rb +20 -5
- data/lib/arel/visitors/dot.rb +81 -90
- data/lib/arel/visitors/mysql.rb +23 -5
- data/lib/arel/visitors/postgresql.rb +1 -22
- data/lib/arel/visitors/to_sql.rb +170 -36
- data/lib/arel/visitors/visitor.rb +2 -2
- data/lib/arel.rb +23 -4
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
- data/lib/rails/generators/active_record/migration.rb +3 -1
- data/lib/rails/generators/active_record/model/USAGE +113 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
- 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 +100 -14
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
- data/lib/active_record/null_relation.rb +0 -67
@@ -14,8 +14,10 @@ module ActiveRecord
|
|
14
14
|
end
|
15
15
|
|
16
16
|
delegate :quote_column_name, :quote_table_name, :quote_default_expression, :type_to_sql,
|
17
|
-
:options_include_default?, :supports_indexes_in_create?, :
|
18
|
-
:quoted_columns_for_index, :supports_partial_index?, :supports_check_constraints?,
|
17
|
+
:options_include_default?, :supports_indexes_in_create?, :use_foreign_keys?,
|
18
|
+
:quoted_columns_for_index, :supports_partial_index?, :supports_check_constraints?,
|
19
|
+
:supports_index_include?, :supports_exclusion_constraints?, :supports_unique_constraints?,
|
20
|
+
:supports_nulls_not_distinct?,
|
19
21
|
to: :@conn, private: true
|
20
22
|
|
21
23
|
private
|
@@ -51,12 +53,20 @@ module ActiveRecord
|
|
51
53
|
statements.concat(o.indexes.map { |column_name, options| index_in_create(o.name, column_name, options) })
|
52
54
|
end
|
53
55
|
|
54
|
-
if
|
55
|
-
statements.concat(o.foreign_keys.map { |
|
56
|
+
if use_foreign_keys?
|
57
|
+
statements.concat(o.foreign_keys.map { |fk| accept fk })
|
56
58
|
end
|
57
59
|
|
58
60
|
if supports_check_constraints?
|
59
|
-
statements.concat(o.check_constraints.map { |
|
61
|
+
statements.concat(o.check_constraints.map { |chk| accept chk })
|
62
|
+
end
|
63
|
+
|
64
|
+
if supports_exclusion_constraints?
|
65
|
+
statements.concat(o.exclusion_constraints.map { |exc| accept exc })
|
66
|
+
end
|
67
|
+
|
68
|
+
if supports_unique_constraints?
|
69
|
+
statements.concat(o.unique_constraints.map { |exc| accept exc })
|
60
70
|
end
|
61
71
|
|
62
72
|
create_sql << "(#{statements.join(', ')})" if statements.present?
|
@@ -70,10 +80,12 @@ module ActiveRecord
|
|
70
80
|
end
|
71
81
|
|
72
82
|
def visit_ForeignKeyDefinition(o)
|
83
|
+
quoted_columns = Array(o.column).map { |c| quote_column_name(c) }
|
84
|
+
quoted_primary_keys = Array(o.primary_key).map { |c| quote_column_name(c) }
|
73
85
|
sql = +<<~SQL
|
74
86
|
CONSTRAINT #{quote_column_name(o.name)}
|
75
|
-
FOREIGN KEY (#{
|
76
|
-
REFERENCES #{quote_table_name(o.to_table)} (#{
|
87
|
+
FOREIGN KEY (#{quoted_columns.join(", ")})
|
88
|
+
REFERENCES #{quote_table_name(o.to_table)} (#{quoted_primary_keys.join(", ")})
|
77
89
|
SQL
|
78
90
|
sql << " #{action_sql('DELETE', o.on_delete)}" if o.on_delete
|
79
91
|
sql << " #{action_sql('UPDATE', o.on_update)}" if o.on_update
|
@@ -100,6 +112,8 @@ module ActiveRecord
|
|
100
112
|
sql << "#{quote_column_name(index.name)} ON #{quote_table_name(index.table)}"
|
101
113
|
sql << "USING #{index.using}" if supports_index_using? && index.using
|
102
114
|
sql << "(#{quoted_columns(index)})"
|
115
|
+
sql << "INCLUDE (#{quoted_include_columns(index.include)})" if supports_index_include? && index.include
|
116
|
+
sql << "NULLS NOT DISTINCT" if supports_nulls_not_distinct? && index.nulls_not_distinct
|
103
117
|
sql << "WHERE #{index.where}" if supports_partial_index? && index.where
|
104
118
|
|
105
119
|
sql.join(" ")
|
@@ -159,19 +173,6 @@ module ActiveRecord
|
|
159
173
|
" TEMPORARY" if o.temporary
|
160
174
|
end
|
161
175
|
|
162
|
-
def foreign_key_in_create(from_table, to_table, options)
|
163
|
-
prefix = ActiveRecord::Base.table_name_prefix
|
164
|
-
suffix = ActiveRecord::Base.table_name_suffix
|
165
|
-
to_table = "#{prefix}#{to_table}#{suffix}"
|
166
|
-
options = foreign_key_options(from_table, to_table, options)
|
167
|
-
accept ForeignKeyDefinition.new(from_table, to_table, options)
|
168
|
-
end
|
169
|
-
|
170
|
-
def check_constraint_in_create(table_name, expression, options)
|
171
|
-
options = check_constraint_options(table_name, expression, options)
|
172
|
-
accept CheckConstraintDefinition.new(table_name, expression, options)
|
173
|
-
end
|
174
|
-
|
175
176
|
def action_sql(action, dependency)
|
176
177
|
case dependency
|
177
178
|
when :nullify then "ON #{action} SET NULL"
|
@@ -1,12 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
|
3
4
|
module ActiveRecord
|
4
|
-
module ConnectionAdapters
|
5
|
+
module ConnectionAdapters # :nodoc:
|
5
6
|
# Abstract representation of an index definition on a table. Instances of
|
6
7
|
# this type are typically created and returned by methods in database
|
7
8
|
# adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes
|
8
9
|
class IndexDefinition # :nodoc:
|
9
|
-
attr_reader :table, :name, :unique, :columns, :lengths, :orders, :opclasses, :where, :type, :using, :comment
|
10
|
+
attr_reader :table, :name, :unique, :columns, :lengths, :orders, :opclasses, :where, :type, :using, :include, :nulls_not_distinct, :comment, :valid
|
10
11
|
|
11
12
|
def initialize(
|
12
13
|
table, name,
|
@@ -18,7 +19,10 @@ module ActiveRecord
|
|
18
19
|
where: nil,
|
19
20
|
type: nil,
|
20
21
|
using: nil,
|
21
|
-
|
22
|
+
include: nil,
|
23
|
+
nulls_not_distinct: nil,
|
24
|
+
comment: nil,
|
25
|
+
valid: true
|
22
26
|
)
|
23
27
|
@table = table
|
24
28
|
@name = name
|
@@ -30,7 +34,14 @@ module ActiveRecord
|
|
30
34
|
@where = where
|
31
35
|
@type = type
|
32
36
|
@using = using
|
37
|
+
@include = include
|
38
|
+
@nulls_not_distinct = nulls_not_distinct
|
33
39
|
@comment = comment
|
40
|
+
@valid = valid
|
41
|
+
end
|
42
|
+
|
43
|
+
def valid?
|
44
|
+
@valid
|
34
45
|
end
|
35
46
|
|
36
47
|
def column_options
|
@@ -41,6 +52,16 @@ module ActiveRecord
|
|
41
52
|
}
|
42
53
|
end
|
43
54
|
|
55
|
+
def defined_for?(columns = nil, name: nil, unique: nil, valid: nil, include: nil, nulls_not_distinct: nil, **options)
|
56
|
+
columns = options[:column] if columns.blank?
|
57
|
+
(columns.nil? || Array(self.columns) == Array(columns).map(&:to_s)) &&
|
58
|
+
(name.nil? || self.name == name.to_s) &&
|
59
|
+
(unique.nil? || self.unique == unique) &&
|
60
|
+
(valid.nil? || self.valid == valid) &&
|
61
|
+
(include.nil? || Array(self.include) == Array(include).map(&:to_s)) &&
|
62
|
+
(nulls_not_distinct.nil? || self.nulls_not_distinct == nulls_not_distinct)
|
63
|
+
end
|
64
|
+
|
44
65
|
private
|
45
66
|
def concise_options(options)
|
46
67
|
if columns.size == options.size && options.values.uniq.size == 1
|
@@ -56,11 +77,24 @@ module ActiveRecord
|
|
56
77
|
# +columns+ attribute of said TableDefinition object, in order to be used
|
57
78
|
# for generating a number of table creation or table changing SQL statements.
|
58
79
|
ColumnDefinition = Struct.new(:name, :type, :options, :sql_type) do # :nodoc:
|
80
|
+
self::OPTION_NAMES = [
|
81
|
+
:limit,
|
82
|
+
:precision,
|
83
|
+
:scale,
|
84
|
+
:default,
|
85
|
+
:null,
|
86
|
+
:collation,
|
87
|
+
:comment,
|
88
|
+
:primary_key,
|
89
|
+
:if_exists,
|
90
|
+
:if_not_exists
|
91
|
+
]
|
92
|
+
|
59
93
|
def primary_key?
|
60
94
|
options[:primary_key]
|
61
95
|
end
|
62
96
|
|
63
|
-
|
97
|
+
(self::OPTION_NAMES - [:primary_key]).each do |option_name|
|
64
98
|
module_eval <<-CODE, __FILE__, __LINE__ + 1
|
65
99
|
def #{option_name}
|
66
100
|
options[:#{option_name}]
|
@@ -79,13 +113,15 @@ module ActiveRecord
|
|
79
113
|
|
80
114
|
AddColumnDefinition = Struct.new(:column) # :nodoc:
|
81
115
|
|
82
|
-
ChangeColumnDefinition = Struct.new(:column, :name)
|
116
|
+
ChangeColumnDefinition = Struct.new(:column, :name) # :nodoc:
|
117
|
+
|
118
|
+
ChangeColumnDefaultDefinition = Struct.new(:column, :default) # :nodoc:
|
83
119
|
|
84
120
|
CreateIndexDefinition = Struct.new(:index, :algorithm, :if_not_exists) # :nodoc:
|
85
121
|
|
86
122
|
PrimaryKeyDefinition = Struct.new(:name) # :nodoc:
|
87
123
|
|
88
|
-
ForeignKeyDefinition = Struct.new(:from_table, :to_table, :options) do
|
124
|
+
ForeignKeyDefinition = Struct.new(:from_table, :to_table, :options) do # :nodoc:
|
89
125
|
def name
|
90
126
|
options[:name]
|
91
127
|
end
|
@@ -106,6 +142,10 @@ module ActiveRecord
|
|
106
142
|
options[:on_update]
|
107
143
|
end
|
108
144
|
|
145
|
+
def deferrable
|
146
|
+
options[:deferrable]
|
147
|
+
end
|
148
|
+
|
109
149
|
def custom_primary_key?
|
110
150
|
options[:primary_key] != default_primary_key
|
111
151
|
end
|
@@ -121,8 +161,8 @@ module ActiveRecord
|
|
121
161
|
|
122
162
|
def defined_for?(to_table: nil, validate: nil, **options)
|
123
163
|
(to_table.nil? || to_table.to_s == self.to_table) &&
|
124
|
-
(validate.nil? || validate == options.fetch(:validate, validate)) &&
|
125
|
-
options.all? { |k, v| self.options[k].to_s == v.to_s }
|
164
|
+
(validate.nil? || validate == self.options.fetch(:validate, validate)) &&
|
165
|
+
options.all? { |k, v| Array(self.options[k]).map(&:to_s) == Array(v).map(&:to_s) }
|
126
166
|
end
|
127
167
|
|
128
168
|
private
|
@@ -144,6 +184,12 @@ module ActiveRecord
|
|
144
184
|
def export_name_on_schema_dump?
|
145
185
|
!ActiveRecord::SchemaDumper.chk_ignore_pattern.match?(name) if name
|
146
186
|
end
|
187
|
+
|
188
|
+
def defined_for?(name:, expression: nil, validate: nil, **options)
|
189
|
+
self.name == name.to_s &&
|
190
|
+
(validate.nil? || validate == self.options.fetch(:validate, validate)) &&
|
191
|
+
options.all? { |k, v| self.options[k].to_s == v.to_s }
|
192
|
+
end
|
147
193
|
end
|
148
194
|
|
149
195
|
class ReferenceDefinition # :nodoc:
|
@@ -167,6 +213,20 @@ module ActiveRecord
|
|
167
213
|
end
|
168
214
|
end
|
169
215
|
|
216
|
+
def add(table_name, connection)
|
217
|
+
columns.each do |name, type, options|
|
218
|
+
connection.add_column(table_name, name, type, **options)
|
219
|
+
end
|
220
|
+
|
221
|
+
if index
|
222
|
+
connection.add_index(table_name, column_names, **index_options(table_name))
|
223
|
+
end
|
224
|
+
|
225
|
+
if foreign_key
|
226
|
+
connection.add_foreign_key(table_name, foreign_table_name, **foreign_key_options)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
170
230
|
def add_to(table)
|
171
231
|
columns.each do |name, type, options|
|
172
232
|
table.column(name, type, **options)
|
@@ -188,8 +248,12 @@ module ActiveRecord
|
|
188
248
|
value.is_a?(Hash) ? value : {}
|
189
249
|
end
|
190
250
|
|
251
|
+
def conditional_options
|
252
|
+
options.slice(:if_exists, :if_not_exists)
|
253
|
+
end
|
254
|
+
|
191
255
|
def polymorphic_options
|
192
|
-
as_options(polymorphic).merge(options.slice(:null, :first, :after))
|
256
|
+
as_options(polymorphic).merge(conditional_options).merge(options.slice(:null, :first, :after))
|
193
257
|
end
|
194
258
|
|
195
259
|
def polymorphic_index_name(table_name)
|
@@ -197,7 +261,7 @@ module ActiveRecord
|
|
197
261
|
end
|
198
262
|
|
199
263
|
def index_options(table_name)
|
200
|
-
index_options = as_options(index)
|
264
|
+
index_options = as_options(index).merge(conditional_options)
|
201
265
|
|
202
266
|
# legacy reference index names are used on versions 6.0 and earlier
|
203
267
|
return index_options if options[:_uses_legacy_reference_index_name]
|
@@ -207,7 +271,7 @@ module ActiveRecord
|
|
207
271
|
end
|
208
272
|
|
209
273
|
def foreign_key_options
|
210
|
-
as_options(foreign_key).merge(column: column_name)
|
274
|
+
as_options(foreign_key).merge(column: column_name, **conditional_options)
|
211
275
|
end
|
212
276
|
|
213
277
|
def columns
|
@@ -257,6 +321,7 @@ module ActiveRecord
|
|
257
321
|
define_column_methods :bigint, :binary, :boolean, :date, :datetime, :decimal,
|
258
322
|
:float, :integer, :json, :string, :text, :time, :timestamp, :virtual
|
259
323
|
|
324
|
+
alias :blob :binary
|
260
325
|
alias :numeric :decimal
|
261
326
|
end
|
262
327
|
|
@@ -275,13 +340,15 @@ module ActiveRecord
|
|
275
340
|
end
|
276
341
|
end
|
277
342
|
|
343
|
+
# = Active Record Connection Adapters \Table \Definition
|
344
|
+
#
|
278
345
|
# Represents the schema of an SQL table in an abstract way. This class
|
279
346
|
# provides methods for manipulating the schema representation.
|
280
347
|
#
|
281
348
|
# Inside migration files, the +t+ object in {create_table}[rdoc-ref:SchemaStatements#create_table]
|
282
349
|
# is actually of this type:
|
283
350
|
#
|
284
|
-
# class SomeMigration < ActiveRecord::Migration[
|
351
|
+
# class SomeMigration < ActiveRecord::Migration[7.2]
|
285
352
|
# def up
|
286
353
|
# create_table :foo do |t|
|
287
354
|
# puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition"
|
@@ -322,6 +389,23 @@ module ActiveRecord
|
|
322
389
|
@comment = comment
|
323
390
|
end
|
324
391
|
|
392
|
+
def set_primary_key(table_name, id, primary_key, **options)
|
393
|
+
if id && !as
|
394
|
+
pk = primary_key || Base.get_primary_key(table_name.to_s.singularize)
|
395
|
+
|
396
|
+
if id.is_a?(Hash)
|
397
|
+
options.merge!(id.except(:type))
|
398
|
+
id = id.fetch(:type, :primary_key)
|
399
|
+
end
|
400
|
+
|
401
|
+
if pk.is_a?(Array)
|
402
|
+
primary_keys(pk)
|
403
|
+
else
|
404
|
+
primary_key(pk, id, **options)
|
405
|
+
end
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
325
409
|
def primary_keys(name = nil) # :nodoc:
|
326
410
|
@primary_keys = PrimaryKeyDefinition.new(name) if name
|
327
411
|
@primary_keys
|
@@ -406,14 +490,7 @@ module ActiveRecord
|
|
406
490
|
name = name.to_s
|
407
491
|
type = type.to_sym if type
|
408
492
|
|
409
|
-
|
410
|
-
if @columns_hash[name].primary_key?
|
411
|
-
raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
|
412
|
-
else
|
413
|
-
raise ArgumentError, "you can't define an already defined column '#{name}'."
|
414
|
-
end
|
415
|
-
end
|
416
|
-
|
493
|
+
raise_on_duplicate_column(name)
|
417
494
|
@columns_hash[name] = new_column_definition(name, type, **options)
|
418
495
|
|
419
496
|
if index
|
@@ -438,12 +515,12 @@ module ActiveRecord
|
|
438
515
|
indexes << [column_name, options]
|
439
516
|
end
|
440
517
|
|
441
|
-
def foreign_key(
|
442
|
-
foreign_keys <<
|
518
|
+
def foreign_key(to_table, **options)
|
519
|
+
foreign_keys << new_foreign_key_definition(to_table, options)
|
443
520
|
end
|
444
521
|
|
445
522
|
def check_constraint(expression, **options)
|
446
|
-
check_constraints <<
|
523
|
+
check_constraints << new_check_constraint_definition(expression, options)
|
447
524
|
end
|
448
525
|
|
449
526
|
# Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
|
@@ -480,13 +557,41 @@ module ActiveRecord
|
|
480
557
|
type = integer_like_primary_key_type(type, options)
|
481
558
|
end
|
482
559
|
type = aliased_types(type.to_s, type)
|
560
|
+
|
561
|
+
if @conn.supports_datetime_with_precision?
|
562
|
+
if type == :datetime && !options.key?(:precision)
|
563
|
+
options[:precision] = 6
|
564
|
+
end
|
565
|
+
end
|
566
|
+
|
483
567
|
options[:primary_key] ||= type == :primary_key
|
484
568
|
options[:null] = false if options[:primary_key]
|
485
569
|
create_column_definition(name, type, options)
|
486
570
|
end
|
487
571
|
|
572
|
+
def new_foreign_key_definition(to_table, options) # :nodoc:
|
573
|
+
prefix = ActiveRecord::Base.table_name_prefix
|
574
|
+
suffix = ActiveRecord::Base.table_name_suffix
|
575
|
+
to_table = "#{prefix}#{to_table}#{suffix}"
|
576
|
+
options = @conn.foreign_key_options(name, to_table, options)
|
577
|
+
ForeignKeyDefinition.new(name, to_table, options)
|
578
|
+
end
|
579
|
+
|
580
|
+
def new_check_constraint_definition(expression, options) # :nodoc:
|
581
|
+
options = @conn.check_constraint_options(name, expression, options)
|
582
|
+
CheckConstraintDefinition.new(name, expression, options)
|
583
|
+
end
|
584
|
+
|
488
585
|
private
|
586
|
+
def valid_column_definition_options
|
587
|
+
@conn.valid_column_definition_options
|
588
|
+
end
|
589
|
+
|
489
590
|
def create_column_definition(name, type, options)
|
591
|
+
unless options[:_skip_validate_options]
|
592
|
+
options.except(:_uses_legacy_reference_index_name, :_skip_validate_options).assert_valid_keys(valid_column_definition_options)
|
593
|
+
end
|
594
|
+
|
490
595
|
ColumnDefinition.new(name, type, options)
|
491
596
|
end
|
492
597
|
|
@@ -501,6 +606,16 @@ module ActiveRecord
|
|
501
606
|
def integer_like_primary_key_type(type, options)
|
502
607
|
type
|
503
608
|
end
|
609
|
+
|
610
|
+
def raise_on_duplicate_column(name)
|
611
|
+
if @columns_hash[name]
|
612
|
+
if @columns_hash[name].primary_key?
|
613
|
+
raise ArgumentError, "you can't redefine the primary key column '#{name}' on '#{@name}'. To define a custom primary key, pass { id: false } to create_table."
|
614
|
+
else
|
615
|
+
raise ArgumentError, "you can't define an already defined column '#{name}' on '#{@name}'."
|
616
|
+
end
|
617
|
+
end
|
618
|
+
end
|
504
619
|
end
|
505
620
|
|
506
621
|
class AlterTable # :nodoc:
|
@@ -520,7 +635,7 @@ module ActiveRecord
|
|
520
635
|
def name; @td.name; end
|
521
636
|
|
522
637
|
def add_foreign_key(to_table, options)
|
523
|
-
@foreign_key_adds <<
|
638
|
+
@foreign_key_adds << @td.new_foreign_key_definition(to_table, options)
|
524
639
|
end
|
525
640
|
|
526
641
|
def drop_foreign_key(name)
|
@@ -528,7 +643,7 @@ module ActiveRecord
|
|
528
643
|
end
|
529
644
|
|
530
645
|
def add_check_constraint(expression, options)
|
531
|
-
@check_constraint_adds <<
|
646
|
+
@check_constraint_adds << @td.new_check_constraint_definition(expression, options)
|
532
647
|
end
|
533
648
|
|
534
649
|
def drop_check_constraint(constraint_name)
|
@@ -542,6 +657,8 @@ module ActiveRecord
|
|
542
657
|
end
|
543
658
|
end
|
544
659
|
|
660
|
+
# = Active Record Connection Adapters \Table
|
661
|
+
#
|
545
662
|
# Represents an SQL table in an abstract way for updating a table.
|
546
663
|
# Also see TableDefinition and {connection.create_table}[rdoc-ref:SchemaStatements#create_table]
|
547
664
|
#
|
@@ -572,6 +689,7 @@ module ActiveRecord
|
|
572
689
|
# t.time
|
573
690
|
# t.date
|
574
691
|
# t.binary
|
692
|
+
# t.blob
|
575
693
|
# t.boolean
|
576
694
|
# t.foreign_key
|
577
695
|
# t.json
|
@@ -601,6 +719,7 @@ module ActiveRecord
|
|
601
719
|
#
|
602
720
|
# See TableDefinition#column for details of the options you can use.
|
603
721
|
def column(column_name, type, index: nil, **options)
|
722
|
+
raise_on_if_exist_options(options)
|
604
723
|
@base.add_column(name, column_name, type, **options)
|
605
724
|
if index
|
606
725
|
index_options = index.is_a?(Hash) ? index : {}
|
@@ -626,6 +745,7 @@ module ActiveRecord
|
|
626
745
|
#
|
627
746
|
# See {connection.add_index}[rdoc-ref:SchemaStatements#add_index] for details of the options you can use.
|
628
747
|
def index(column_name, **options)
|
748
|
+
raise_on_if_exist_options(options)
|
629
749
|
@base.add_index(name, column_name, **options)
|
630
750
|
end
|
631
751
|
|
@@ -636,8 +756,8 @@ module ActiveRecord
|
|
636
756
|
# end
|
637
757
|
#
|
638
758
|
# See {connection.index_exists?}[rdoc-ref:SchemaStatements#index_exists?]
|
639
|
-
def index_exists?(column_name, options
|
640
|
-
@base.index_exists?(name, column_name, options)
|
759
|
+
def index_exists?(column_name, **options)
|
760
|
+
@base.index_exists?(name, column_name, **options)
|
641
761
|
end
|
642
762
|
|
643
763
|
# Renames the given index on the table.
|
@@ -655,6 +775,7 @@ module ActiveRecord
|
|
655
775
|
#
|
656
776
|
# See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
|
657
777
|
def timestamps(**options)
|
778
|
+
raise_on_if_exist_options(options)
|
658
779
|
@base.add_timestamps(name, **options)
|
659
780
|
end
|
660
781
|
|
@@ -665,6 +786,7 @@ module ActiveRecord
|
|
665
786
|
#
|
666
787
|
# See TableDefinition#column for details of the options you can use.
|
667
788
|
def change(column_name, type, **options)
|
789
|
+
raise_on_if_exist_options(options)
|
668
790
|
@base.change_column(name, column_name, type, **options)
|
669
791
|
end
|
670
792
|
|
@@ -696,6 +818,7 @@ module ActiveRecord
|
|
696
818
|
#
|
697
819
|
# See {connection.remove_columns}[rdoc-ref:SchemaStatements#remove_columns]
|
698
820
|
def remove(*column_names, **options)
|
821
|
+
raise_on_if_exist_options(options)
|
699
822
|
@base.remove_columns(name, *column_names, **options)
|
700
823
|
end
|
701
824
|
|
@@ -708,6 +831,7 @@ module ActiveRecord
|
|
708
831
|
#
|
709
832
|
# See {connection.remove_index}[rdoc-ref:SchemaStatements#remove_index]
|
710
833
|
def remove_index(column_name = nil, **options)
|
834
|
+
raise_on_if_exist_options(options)
|
711
835
|
@base.remove_index(name, column_name, **options)
|
712
836
|
end
|
713
837
|
|
@@ -736,6 +860,7 @@ module ActiveRecord
|
|
736
860
|
#
|
737
861
|
# See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
|
738
862
|
def references(*args, **options)
|
863
|
+
raise_on_if_exist_options(options)
|
739
864
|
args.each do |ref_name|
|
740
865
|
@base.add_reference(name, ref_name, **options)
|
741
866
|
end
|
@@ -749,6 +874,7 @@ module ActiveRecord
|
|
749
874
|
#
|
750
875
|
# See {connection.remove_reference}[rdoc-ref:SchemaStatements#remove_reference]
|
751
876
|
def remove_references(*args, **options)
|
877
|
+
raise_on_if_exist_options(options)
|
752
878
|
args.each do |ref_name|
|
753
879
|
@base.remove_reference(name, ref_name, **options)
|
754
880
|
end
|
@@ -762,6 +888,7 @@ module ActiveRecord
|
|
762
888
|
#
|
763
889
|
# See {connection.add_foreign_key}[rdoc-ref:SchemaStatements#add_foreign_key]
|
764
890
|
def foreign_key(*args, **options)
|
891
|
+
raise_on_if_exist_options(options)
|
765
892
|
@base.add_foreign_key(name, *args, **options)
|
766
893
|
end
|
767
894
|
|
@@ -772,6 +899,7 @@ module ActiveRecord
|
|
772
899
|
#
|
773
900
|
# See {connection.remove_foreign_key}[rdoc-ref:SchemaStatements#remove_foreign_key]
|
774
901
|
def remove_foreign_key(*args, **options)
|
902
|
+
raise_on_if_exist_options(options)
|
775
903
|
@base.remove_foreign_key(name, *args, **options)
|
776
904
|
end
|
777
905
|
|
@@ -789,8 +917,8 @@ module ActiveRecord
|
|
789
917
|
# t.check_constraint("price > 0", name: "price_check")
|
790
918
|
#
|
791
919
|
# See {connection.add_check_constraint}[rdoc-ref:SchemaStatements#add_check_constraint]
|
792
|
-
def check_constraint(*args)
|
793
|
-
@base.add_check_constraint(name, *args)
|
920
|
+
def check_constraint(*args, **options)
|
921
|
+
@base.add_check_constraint(name, *args, **options)
|
794
922
|
end
|
795
923
|
|
796
924
|
# Removes the given check constraint from the table.
|
@@ -798,9 +926,36 @@ module ActiveRecord
|
|
798
926
|
# t.remove_check_constraint(name: "price_check")
|
799
927
|
#
|
800
928
|
# See {connection.remove_check_constraint}[rdoc-ref:SchemaStatements#remove_check_constraint]
|
801
|
-
def remove_check_constraint(*args)
|
802
|
-
@base.remove_check_constraint(name, *args)
|
929
|
+
def remove_check_constraint(*args, **options)
|
930
|
+
@base.remove_check_constraint(name, *args, **options)
|
931
|
+
end
|
932
|
+
|
933
|
+
# Checks if a check_constraint exists on a table.
|
934
|
+
#
|
935
|
+
# unless t.check_constraint_exists?(name: "price_check")
|
936
|
+
# t.check_constraint("price > 0", name: "price_check")
|
937
|
+
# end
|
938
|
+
#
|
939
|
+
# See {connection.check_constraint_exists?}[rdoc-ref:SchemaStatements#check_constraint_exists?]
|
940
|
+
def check_constraint_exists?(*args, **options)
|
941
|
+
@base.check_constraint_exists?(name, *args, **options)
|
803
942
|
end
|
943
|
+
|
944
|
+
private
|
945
|
+
def raise_on_if_exist_options(options)
|
946
|
+
unrecognized_option = options.keys.find do |key|
|
947
|
+
key == :if_exists || key == :if_not_exists
|
948
|
+
end
|
949
|
+
if unrecognized_option
|
950
|
+
conditional = unrecognized_option == :if_exists ? "if" : "unless"
|
951
|
+
message = <<~TXT
|
952
|
+
Option #{unrecognized_option} will be ignored. If you are calling an expression like
|
953
|
+
`t.column(.., #{unrecognized_option}: true)` from inside a change_table block, try a
|
954
|
+
conditional clause instead, as in `t.column(..) #{conditional} t.column_exists?(..)`
|
955
|
+
TXT
|
956
|
+
raise ArgumentError.new(message)
|
957
|
+
end
|
958
|
+
end
|
804
959
|
end
|
805
960
|
end
|
806
961
|
end
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module ActiveRecord
|
4
4
|
module ConnectionAdapters # :nodoc:
|
5
5
|
class SchemaDumper < SchemaDumper # :nodoc:
|
6
|
+
DEFAULT_DATETIME_PRECISION = 6 # :nodoc:
|
7
|
+
|
6
8
|
def self.create(connection, options)
|
7
9
|
new(connection, options)
|
8
10
|
end
|
@@ -63,7 +65,18 @@ module ActiveRecord
|
|
63
65
|
end
|
64
66
|
|
65
67
|
def schema_precision(column)
|
66
|
-
column.
|
68
|
+
if column.type == :datetime
|
69
|
+
case column.precision
|
70
|
+
when nil
|
71
|
+
"nil"
|
72
|
+
when DEFAULT_DATETIME_PRECISION
|
73
|
+
nil
|
74
|
+
else
|
75
|
+
column.precision.inspect
|
76
|
+
end
|
77
|
+
elsif column.precision
|
78
|
+
column.precision.inspect
|
79
|
+
end
|
67
80
|
end
|
68
81
|
|
69
82
|
def schema_scale(column)
|