activerecord 7.0.8.7 → 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 +781 -1777
- data/MIT-LICENSE +1 -1
- data/README.rdoc +30 -30
- data/examples/performance.rb +2 -2
- data/lib/active_record/aggregations.rb +16 -13
- data/lib/active_record/association_relation.rb +2 -2
- data/lib/active_record/associations/alias_tracker.rb +31 -23
- data/lib/active_record/associations/association.rb +35 -12
- data/lib/active_record/associations/association_scope.rb +16 -9
- data/lib/active_record/associations/belongs_to_association.rb +40 -9
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
- data/lib/active_record/associations/builder/association.rb +3 -3
- data/lib/active_record/associations/builder/belongs_to.rb +22 -8
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -7
- data/lib/active_record/associations/builder/has_many.rb +3 -4
- data/lib/active_record/associations/builder/has_one.rb +3 -4
- data/lib/active_record/associations/builder/singular_association.rb +4 -0
- data/lib/active_record/associations/collection_association.rb +35 -21
- data/lib/active_record/associations/collection_proxy.rb +29 -11
- 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 +21 -14
- data/lib/active_record/associations/has_many_through_association.rb +17 -7
- data/lib/active_record/associations/has_one_association.rb +10 -3
- data/lib/active_record/associations/join_dependency/join_association.rb +4 -3
- data/lib/active_record/associations/join_dependency.rb +10 -10
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +33 -8
- data/lib/active_record/associations/preloader/branch.rb +7 -1
- data/lib/active_record/associations/preloader/through_association.rb +1 -3
- data/lib/active_record/associations/preloader.rb +13 -10
- data/lib/active_record/associations/singular_association.rb +7 -1
- data/lib/active_record/associations/through_association.rb +22 -11
- data/lib/active_record/associations.rb +354 -485
- data/lib/active_record/attribute_assignment.rb +0 -4
- data/lib/active_record/attribute_methods/before_type_cast.rb +17 -0
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/dirty.rb +53 -35
- data/lib/active_record/attribute_methods/primary_key.rb +45 -25
- data/lib/active_record/attribute_methods/query.rb +28 -16
- data/lib/active_record/attribute_methods/read.rb +8 -7
- data/lib/active_record/attribute_methods/serialization.rb +131 -32
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +11 -6
- data/lib/active_record/attribute_methods/write.rb +6 -6
- data/lib/active_record/attribute_methods.rb +153 -33
- data/lib/active_record/attributes.rb +96 -71
- data/lib/active_record/autosave_association.rb +81 -39
- data/lib/active_record/base.rb +11 -7
- data/lib/active_record/callbacks.rb +11 -25
- 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 -42
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +123 -131
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +4 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +343 -91
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +160 -45
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +229 -64
- data/lib/active_record/connection_adapters/abstract/quoting.rb +72 -63
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +18 -4
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +142 -12
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +310 -129
- data/lib/active_record/connection_adapters/abstract/transaction.rb +367 -75
- data/lib/active_record/connection_adapters/abstract_adapter.rb +539 -111
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +289 -128
- data/lib/active_record/connection_adapters/column.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +26 -139
- data/lib/active_record/connection_adapters/mysql/quoting.rb +60 -55
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +6 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +25 -13
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +108 -68
- data/lib/active_record/connection_adapters/pool_config.rb +20 -10
- data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +14 -3
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +100 -43
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +11 -2
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +65 -61
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +3 -9
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -6
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +153 -2
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +54 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +371 -64
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +374 -203
- data/lib/active_record/connection_adapters/schema_cache.rb +302 -79
- data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +60 -43
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +57 -45
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +14 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +51 -8
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +298 -113
- 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 +124 -1
- data/lib/active_record/connection_handling.rb +101 -105
- data/lib/active_record/core.rb +273 -178
- data/lib/active_record/counter_cache.rb +69 -35
- data/lib/active_record/database_configurations/connection_url_resolver.rb +10 -3
- data/lib/active_record/database_configurations/database_config.rb +26 -5
- data/lib/active_record/database_configurations/hash_config.rb +52 -34
- data/lib/active_record/database_configurations/url_config.rb +37 -12
- data/lib/active_record/database_configurations.rb +87 -34
- data/lib/active_record/delegated_type.rb +56 -27
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +3 -1
- data/lib/active_record/dynamic_matchers.rb +2 -2
- data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +4 -1
- data/lib/active_record/encryption/config.rb +25 -1
- data/lib/active_record/encryption/configurable.rb +12 -19
- data/lib/active_record/encryption/context.rb +10 -3
- data/lib/active_record/encryption/contexts.rb +5 -1
- data/lib/active_record/encryption/derived_secret_key_provider.rb +8 -2
- data/lib/active_record/encryption/encryptable_record.rb +46 -22
- data/lib/active_record/encryption/encrypted_attribute_type.rb +48 -13
- data/lib/active_record/encryption/encryptor.rb +35 -19
- data/lib/active_record/encryption/extended_deterministic_queries.rb +66 -69
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +3 -3
- data/lib/active_record/encryption/key_generator.rb +12 -1
- data/lib/active_record/encryption/key_provider.rb +1 -1
- data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
- data/lib/active_record/encryption/message_serializer.rb +6 -0
- data/lib/active_record/encryption/null_encryptor.rb +4 -0
- data/lib/active_record/encryption/properties.rb +3 -3
- data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
- data/lib/active_record/encryption/scheme.rb +22 -21
- data/lib/active_record/encryption.rb +3 -0
- data/lib/active_record/enum.rb +130 -28
- data/lib/active_record/errors.rb +154 -34
- data/lib/active_record/explain.rb +21 -12
- 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 +48 -10
- data/lib/active_record/fixtures.rb +167 -97
- data/lib/active_record/future_result.rb +47 -8
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +34 -18
- data/lib/active_record/insert_all.rb +72 -22
- data/lib/active_record/integration.rb +11 -8
- data/lib/active_record/internal_metadata.rb +124 -20
- data/lib/active_record/locking/optimistic.rb +8 -7
- data/lib/active_record/locking/pessimistic.rb +5 -2
- data/lib/active_record/log_subscriber.rb +18 -22
- 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.rb +4 -0
- data/lib/active_record/middleware/database_selector.rb +6 -8
- data/lib/active_record/middleware/shard_selector.rb +3 -1
- data/lib/active_record/migration/command_recorder.rb +106 -8
- data/lib/active_record/migration/compatibility.rb +147 -5
- 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/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +236 -118
- data/lib/active_record/model_schema.rb +90 -102
- data/lib/active_record/nested_attributes.rb +48 -11
- data/lib/active_record/normalization.rb +163 -0
- data/lib/active_record/persistence.rb +168 -339
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +18 -25
- data/lib/active_record/query_logs.rb +96 -52
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +35 -10
- data/lib/active_record/railtie.rb +131 -87
- data/lib/active_record/railties/controller_runtime.rb +22 -7
- data/lib/active_record/railties/databases.rake +147 -155
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +32 -5
- data/lib/active_record/reflection.rb +267 -69
- data/lib/active_record/relation/batches/batch_enumerator.rb +20 -5
- data/lib/active_record/relation/batches.rb +198 -63
- data/lib/active_record/relation/calculations.rb +270 -108
- data/lib/active_record/relation/delegation.rb +30 -19
- data/lib/active_record/relation/finder_methods.rb +97 -21
- data/lib/active_record/relation/merger.rb +6 -6
- data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +20 -3
- 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 +28 -16
- data/lib/active_record/relation/query_attribute.rb +3 -2
- data/lib/active_record/relation/query_methods.rb +585 -109
- data/lib/active_record/relation/record_fetch_warning.rb +3 -0
- data/lib/active_record/relation/spawn_methods.rb +5 -4
- data/lib/active_record/relation/where_clause.rb +15 -21
- data/lib/active_record/relation.rb +592 -92
- data/lib/active_record/result.rb +49 -48
- data/lib/active_record/runtime_registry.rb +63 -1
- data/lib/active_record/sanitization.rb +70 -25
- data/lib/active_record/schema.rb +8 -7
- data/lib/active_record/schema_dumper.rb +90 -23
- data/lib/active_record/schema_migration.rb +75 -24
- data/lib/active_record/scoping/default.rb +15 -5
- data/lib/active_record/scoping/named.rb +3 -2
- data/lib/active_record/scoping.rb +2 -1
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +21 -3
- data/lib/active_record/signed_id.rb +33 -11
- data/lib/active_record/statement_cache.rb +7 -7
- data/lib/active_record/store.rb +8 -8
- data/lib/active_record/suppressor.rb +3 -1
- data/lib/active_record/table_metadata.rb +1 -1
- data/lib/active_record/tasks/database_tasks.rb +190 -118
- data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
- data/lib/active_record/tasks/postgresql_database_tasks.rb +23 -13
- data/lib/active_record/tasks/sqlite_database_tasks.rb +16 -7
- data/lib/active_record/test_fixtures.rb +170 -155
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +31 -17
- 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 +108 -24
- data/lib/active_record/translation.rb +0 -2
- data/lib/active_record/type/adapter_specific_registry.rb +1 -8
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/serialized.rb +1 -3
- data/lib/active_record/type/time.rb +4 -0
- 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 +9 -3
- 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 +61 -11
- data/lib/active_record/validations.rb +12 -5
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +247 -33
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/collectors/bind.rb +3 -1
- 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 +2 -0
- data/lib/arel/delete_manager.rb +5 -0
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.rb +4 -0
- data/lib/arel/nodes/binary.rb +6 -7
- data/lib/arel/nodes/bound_sql_literal.rb +65 -0
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/delete_statement.rb +4 -2
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/homogeneous_in.rb +1 -9
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
- data/lib/arel/nodes/node.rb +115 -5
- 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 +4 -2
- data/lib/arel/nodes.rb +6 -2
- data/lib/arel/predications.rb +3 -1
- data/lib/arel/select_manager.rb +7 -3
- data/lib/arel/table.rb +9 -5
- data/lib/arel/tree_manager.rb +8 -3
- data/lib/arel/update_manager.rb +7 -1
- data/lib/arel/visitors/dot.rb +3 -0
- data/lib/arel/visitors/mysql.rb +17 -5
- data/lib/arel/visitors/postgresql.rb +1 -12
- data/lib/arel/visitors/sqlite.rb +25 -0
- data/lib/arel/visitors/to_sql.rb +114 -34
- data/lib/arel/visitors/visitor.rb +2 -2
- data/lib/arel.rb +21 -3
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- 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
- metadata +56 -17
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
- data/lib/active_record/null_relation.rb +0 -63
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
module ActiveRecord
|
|
4
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}]
|
|
@@ -81,6 +115,8 @@ module ActiveRecord
|
|
|
81
115
|
|
|
82
116
|
ChangeColumnDefinition = Struct.new(:column, :name) # :nodoc:
|
|
83
117
|
|
|
118
|
+
ChangeColumnDefaultDefinition = Struct.new(:column, :default) # :nodoc:
|
|
119
|
+
|
|
84
120
|
CreateIndexDefinition = Struct.new(:index, :algorithm, :if_not_exists) # :nodoc:
|
|
85
121
|
|
|
86
122
|
PrimaryKeyDefinition = Struct.new(:name) # :nodoc:
|
|
@@ -124,9 +160,11 @@ module ActiveRecord
|
|
|
124
160
|
end
|
|
125
161
|
|
|
126
162
|
def defined_for?(to_table: nil, validate: nil, **options)
|
|
163
|
+
options = options.slice(*self.options.keys)
|
|
164
|
+
|
|
127
165
|
(to_table.nil? || to_table.to_s == self.to_table) &&
|
|
128
|
-
(validate.nil? || validate == options.fetch(:validate, validate)) &&
|
|
129
|
-
options.all? { |k, v| self.options[k].to_s == v.to_s }
|
|
166
|
+
(validate.nil? || validate == self.options.fetch(:validate, validate)) &&
|
|
167
|
+
options.all? { |k, v| Array(self.options[k]).map(&:to_s) == Array(v).map(&:to_s) }
|
|
130
168
|
end
|
|
131
169
|
|
|
132
170
|
private
|
|
@@ -148,6 +186,14 @@ module ActiveRecord
|
|
|
148
186
|
def export_name_on_schema_dump?
|
|
149
187
|
!ActiveRecord::SchemaDumper.chk_ignore_pattern.match?(name) if name
|
|
150
188
|
end
|
|
189
|
+
|
|
190
|
+
def defined_for?(name:, expression: nil, validate: nil, **options)
|
|
191
|
+
options = options.slice(*self.options.keys)
|
|
192
|
+
|
|
193
|
+
self.name == name.to_s &&
|
|
194
|
+
(validate.nil? || validate == self.options.fetch(:validate, validate)) &&
|
|
195
|
+
options.all? { |k, v| self.options[k].to_s == v.to_s }
|
|
196
|
+
end
|
|
151
197
|
end
|
|
152
198
|
|
|
153
199
|
class ReferenceDefinition # :nodoc:
|
|
@@ -171,6 +217,20 @@ module ActiveRecord
|
|
|
171
217
|
end
|
|
172
218
|
end
|
|
173
219
|
|
|
220
|
+
def add(table_name, connection)
|
|
221
|
+
columns.each do |name, type, options|
|
|
222
|
+
connection.add_column(table_name, name, type, **options)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
if index
|
|
226
|
+
connection.add_index(table_name, column_names, **index_options(table_name))
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
if foreign_key
|
|
230
|
+
connection.add_foreign_key(table_name, foreign_table_name, **foreign_key_options)
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
174
234
|
def add_to(table)
|
|
175
235
|
columns.each do |name, type, options|
|
|
176
236
|
table.column(name, type, **options)
|
|
@@ -192,8 +252,12 @@ module ActiveRecord
|
|
|
192
252
|
value.is_a?(Hash) ? value : {}
|
|
193
253
|
end
|
|
194
254
|
|
|
255
|
+
def conditional_options
|
|
256
|
+
options.slice(:if_exists, :if_not_exists)
|
|
257
|
+
end
|
|
258
|
+
|
|
195
259
|
def polymorphic_options
|
|
196
|
-
as_options(polymorphic).merge(options.slice(:null, :first, :after))
|
|
260
|
+
as_options(polymorphic).merge(conditional_options).merge(options.slice(:null, :first, :after))
|
|
197
261
|
end
|
|
198
262
|
|
|
199
263
|
def polymorphic_index_name(table_name)
|
|
@@ -201,7 +265,7 @@ module ActiveRecord
|
|
|
201
265
|
end
|
|
202
266
|
|
|
203
267
|
def index_options(table_name)
|
|
204
|
-
index_options = as_options(index)
|
|
268
|
+
index_options = as_options(index).merge(conditional_options)
|
|
205
269
|
|
|
206
270
|
# legacy reference index names are used on versions 6.0 and earlier
|
|
207
271
|
return index_options if options[:_uses_legacy_reference_index_name]
|
|
@@ -211,7 +275,7 @@ module ActiveRecord
|
|
|
211
275
|
end
|
|
212
276
|
|
|
213
277
|
def foreign_key_options
|
|
214
|
-
as_options(foreign_key).merge(column: column_name)
|
|
278
|
+
as_options(foreign_key).merge(column: column_name, **conditional_options)
|
|
215
279
|
end
|
|
216
280
|
|
|
217
281
|
def columns
|
|
@@ -280,13 +344,15 @@ module ActiveRecord
|
|
|
280
344
|
end
|
|
281
345
|
end
|
|
282
346
|
|
|
347
|
+
# = Active Record Connection Adapters \Table \Definition
|
|
348
|
+
#
|
|
283
349
|
# Represents the schema of an SQL table in an abstract way. This class
|
|
284
350
|
# provides methods for manipulating the schema representation.
|
|
285
351
|
#
|
|
286
352
|
# Inside migration files, the +t+ object in {create_table}[rdoc-ref:SchemaStatements#create_table]
|
|
287
353
|
# is actually of this type:
|
|
288
354
|
#
|
|
289
|
-
# class SomeMigration < ActiveRecord::Migration[7.
|
|
355
|
+
# class SomeMigration < ActiveRecord::Migration[7.2]
|
|
290
356
|
# def up
|
|
291
357
|
# create_table :foo do |t|
|
|
292
358
|
# puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition"
|
|
@@ -327,6 +393,23 @@ module ActiveRecord
|
|
|
327
393
|
@comment = comment
|
|
328
394
|
end
|
|
329
395
|
|
|
396
|
+
def set_primary_key(table_name, id, primary_key, **options)
|
|
397
|
+
if id && !as
|
|
398
|
+
pk = primary_key || Base.get_primary_key(table_name.to_s.singularize)
|
|
399
|
+
|
|
400
|
+
if id.is_a?(Hash)
|
|
401
|
+
options.merge!(id.except(:type))
|
|
402
|
+
id = id.fetch(:type, :primary_key)
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
if pk.is_a?(Array)
|
|
406
|
+
primary_keys(pk)
|
|
407
|
+
else
|
|
408
|
+
primary_key(pk, id, **options)
|
|
409
|
+
end
|
|
410
|
+
end
|
|
411
|
+
end
|
|
412
|
+
|
|
330
413
|
def primary_keys(name = nil) # :nodoc:
|
|
331
414
|
@primary_keys = PrimaryKeyDefinition.new(name) if name
|
|
332
415
|
@primary_keys
|
|
@@ -352,7 +435,7 @@ module ActiveRecord
|
|
|
352
435
|
#
|
|
353
436
|
# == Examples
|
|
354
437
|
#
|
|
355
|
-
# # Assuming
|
|
438
|
+
# # Assuming `td` is an instance of TableDefinition
|
|
356
439
|
# td.column(:granted, :boolean, index: true)
|
|
357
440
|
#
|
|
358
441
|
# == Short-hand examples
|
|
@@ -504,7 +587,15 @@ module ActiveRecord
|
|
|
504
587
|
end
|
|
505
588
|
|
|
506
589
|
private
|
|
590
|
+
def valid_column_definition_options
|
|
591
|
+
@conn.valid_column_definition_options
|
|
592
|
+
end
|
|
593
|
+
|
|
507
594
|
def create_column_definition(name, type, options)
|
|
595
|
+
unless options[:_skip_validate_options]
|
|
596
|
+
options.except(:_uses_legacy_reference_index_name, :_skip_validate_options).assert_valid_keys(valid_column_definition_options)
|
|
597
|
+
end
|
|
598
|
+
|
|
508
599
|
ColumnDefinition.new(name, type, options)
|
|
509
600
|
end
|
|
510
601
|
|
|
@@ -523,9 +614,9 @@ module ActiveRecord
|
|
|
523
614
|
def raise_on_duplicate_column(name)
|
|
524
615
|
if @columns_hash[name]
|
|
525
616
|
if @columns_hash[name].primary_key?
|
|
526
|
-
raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
|
|
617
|
+
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."
|
|
527
618
|
else
|
|
528
|
-
raise ArgumentError, "you can't define an already defined column '#{name}'."
|
|
619
|
+
raise ArgumentError, "you can't define an already defined column '#{name}' on '#{@name}'."
|
|
529
620
|
end
|
|
530
621
|
end
|
|
531
622
|
end
|
|
@@ -570,6 +661,8 @@ module ActiveRecord
|
|
|
570
661
|
end
|
|
571
662
|
end
|
|
572
663
|
|
|
664
|
+
# = Active Record Connection Adapters \Table
|
|
665
|
+
#
|
|
573
666
|
# Represents an SQL table in an abstract way for updating a table.
|
|
574
667
|
# Also see TableDefinition and {connection.create_table}[rdoc-ref:SchemaStatements#create_table]
|
|
575
668
|
#
|
|
@@ -630,6 +723,7 @@ module ActiveRecord
|
|
|
630
723
|
#
|
|
631
724
|
# See TableDefinition#column for details of the options you can use.
|
|
632
725
|
def column(column_name, type, index: nil, **options)
|
|
726
|
+
raise_on_if_exist_options(options)
|
|
633
727
|
@base.add_column(name, column_name, type, **options)
|
|
634
728
|
if index
|
|
635
729
|
index_options = index.is_a?(Hash) ? index : {}
|
|
@@ -655,6 +749,7 @@ module ActiveRecord
|
|
|
655
749
|
#
|
|
656
750
|
# See {connection.add_index}[rdoc-ref:SchemaStatements#add_index] for details of the options you can use.
|
|
657
751
|
def index(column_name, **options)
|
|
752
|
+
raise_on_if_exist_options(options)
|
|
658
753
|
@base.add_index(name, column_name, **options)
|
|
659
754
|
end
|
|
660
755
|
|
|
@@ -684,6 +779,7 @@ module ActiveRecord
|
|
|
684
779
|
#
|
|
685
780
|
# See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
|
|
686
781
|
def timestamps(**options)
|
|
782
|
+
raise_on_if_exist_options(options)
|
|
687
783
|
@base.add_timestamps(name, **options)
|
|
688
784
|
end
|
|
689
785
|
|
|
@@ -694,6 +790,7 @@ module ActiveRecord
|
|
|
694
790
|
#
|
|
695
791
|
# See TableDefinition#column for details of the options you can use.
|
|
696
792
|
def change(column_name, type, **options)
|
|
793
|
+
raise_on_if_exist_options(options)
|
|
697
794
|
@base.change_column(name, column_name, type, **options)
|
|
698
795
|
end
|
|
699
796
|
|
|
@@ -725,6 +822,7 @@ module ActiveRecord
|
|
|
725
822
|
#
|
|
726
823
|
# See {connection.remove_columns}[rdoc-ref:SchemaStatements#remove_columns]
|
|
727
824
|
def remove(*column_names, **options)
|
|
825
|
+
raise_on_if_exist_options(options)
|
|
728
826
|
@base.remove_columns(name, *column_names, **options)
|
|
729
827
|
end
|
|
730
828
|
|
|
@@ -737,6 +835,7 @@ module ActiveRecord
|
|
|
737
835
|
#
|
|
738
836
|
# See {connection.remove_index}[rdoc-ref:SchemaStatements#remove_index]
|
|
739
837
|
def remove_index(column_name = nil, **options)
|
|
838
|
+
raise_on_if_exist_options(options)
|
|
740
839
|
@base.remove_index(name, column_name, **options)
|
|
741
840
|
end
|
|
742
841
|
|
|
@@ -765,6 +864,7 @@ module ActiveRecord
|
|
|
765
864
|
#
|
|
766
865
|
# See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
|
|
767
866
|
def references(*args, **options)
|
|
867
|
+
raise_on_if_exist_options(options)
|
|
768
868
|
args.each do |ref_name|
|
|
769
869
|
@base.add_reference(name, ref_name, **options)
|
|
770
870
|
end
|
|
@@ -778,6 +878,7 @@ module ActiveRecord
|
|
|
778
878
|
#
|
|
779
879
|
# See {connection.remove_reference}[rdoc-ref:SchemaStatements#remove_reference]
|
|
780
880
|
def remove_references(*args, **options)
|
|
881
|
+
raise_on_if_exist_options(options)
|
|
781
882
|
args.each do |ref_name|
|
|
782
883
|
@base.remove_reference(name, ref_name, **options)
|
|
783
884
|
end
|
|
@@ -791,6 +892,7 @@ module ActiveRecord
|
|
|
791
892
|
#
|
|
792
893
|
# See {connection.add_foreign_key}[rdoc-ref:SchemaStatements#add_foreign_key]
|
|
793
894
|
def foreign_key(*args, **options)
|
|
895
|
+
raise_on_if_exist_options(options)
|
|
794
896
|
@base.add_foreign_key(name, *args, **options)
|
|
795
897
|
end
|
|
796
898
|
|
|
@@ -801,6 +903,7 @@ module ActiveRecord
|
|
|
801
903
|
#
|
|
802
904
|
# See {connection.remove_foreign_key}[rdoc-ref:SchemaStatements#remove_foreign_key]
|
|
803
905
|
def remove_foreign_key(*args, **options)
|
|
906
|
+
raise_on_if_exist_options(options)
|
|
804
907
|
@base.remove_foreign_key(name, *args, **options)
|
|
805
908
|
end
|
|
806
909
|
|
|
@@ -830,6 +933,33 @@ module ActiveRecord
|
|
|
830
933
|
def remove_check_constraint(*args, **options)
|
|
831
934
|
@base.remove_check_constraint(name, *args, **options)
|
|
832
935
|
end
|
|
936
|
+
|
|
937
|
+
# Checks if a check_constraint exists on a table.
|
|
938
|
+
#
|
|
939
|
+
# unless t.check_constraint_exists?(name: "price_check")
|
|
940
|
+
# t.check_constraint("price > 0", name: "price_check")
|
|
941
|
+
# end
|
|
942
|
+
#
|
|
943
|
+
# See {connection.check_constraint_exists?}[rdoc-ref:SchemaStatements#check_constraint_exists?]
|
|
944
|
+
def check_constraint_exists?(*args, **options)
|
|
945
|
+
@base.check_constraint_exists?(name, *args, **options)
|
|
946
|
+
end
|
|
947
|
+
|
|
948
|
+
private
|
|
949
|
+
def raise_on_if_exist_options(options)
|
|
950
|
+
unrecognized_option = options.keys.find do |key|
|
|
951
|
+
key == :if_exists || key == :if_not_exists
|
|
952
|
+
end
|
|
953
|
+
if unrecognized_option
|
|
954
|
+
conditional = unrecognized_option == :if_exists ? "if" : "unless"
|
|
955
|
+
message = <<~TXT
|
|
956
|
+
Option #{unrecognized_option} will be ignored. If you are calling an expression like
|
|
957
|
+
`t.column(.., #{unrecognized_option}: true)` from inside a change_table block, try a
|
|
958
|
+
conditional clause instead, as in `t.column(..) #{conditional} t.column_exists?(..)`
|
|
959
|
+
TXT
|
|
960
|
+
raise ArgumentError.new(message)
|
|
961
|
+
end
|
|
962
|
+
end
|
|
833
963
|
end
|
|
834
964
|
end
|
|
835
965
|
end
|