activerecord 7.1.5.2 → 8.1.2.1
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 +567 -2443
- data/README.rdoc +16 -16
- data/examples/performance.rb +2 -2
- data/lib/active_record/association_relation.rb +3 -2
- data/lib/active_record/associations/alias_tracker.rb +31 -23
- data/lib/active_record/associations/association.rb +43 -12
- data/lib/active_record/associations/belongs_to_association.rb +31 -8
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
- data/lib/active_record/associations/builder/association.rb +23 -11
- data/lib/active_record/associations/builder/belongs_to.rb +18 -4
- data/lib/active_record/associations/builder/collection_association.rb +7 -3
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -2
- 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 +33 -5
- data/lib/active_record/associations/collection_association.rb +17 -9
- data/lib/active_record/associations/collection_proxy.rb +36 -5
- data/lib/active_record/associations/deprecation.rb +88 -0
- data/lib/active_record/associations/disable_joins_association_scope.rb +1 -1
- data/lib/active_record/associations/errors.rb +268 -0
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +10 -3
- data/lib/active_record/associations/join_dependency/join_association.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +4 -2
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +4 -3
- data/lib/active_record/associations/preloader/batch.rb +7 -1
- data/lib/active_record/associations/preloader/branch.rb +8 -1
- data/lib/active_record/associations/preloader/through_association.rb +1 -3
- data/lib/active_record/associations/singular_association.rb +14 -3
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +250 -315
- data/lib/active_record/asynchronous_queries_tracker.rb +28 -24
- data/lib/active_record/attribute_assignment.rb +0 -2
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/primary_key.rb +25 -61
- data/lib/active_record/attribute_methods/query.rb +34 -0
- data/lib/active_record/attribute_methods/read.rb +1 -13
- data/lib/active_record/attribute_methods/serialization.rb +20 -27
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +19 -20
- data/lib/active_record/attribute_methods.rb +71 -75
- data/lib/active_record/attributes.rb +96 -68
- data/lib/active_record/autosave_association.rb +93 -58
- data/lib/active_record/base.rb +5 -7
- data/lib/active_record/callbacks.rb +1 -1
- data/lib/active_record/coders/json.rb +14 -5
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +50 -126
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +16 -4
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +52 -13
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +681 -135
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +165 -86
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +226 -78
- data/lib/active_record/connection_adapters/abstract/quoting.rb +79 -114
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +11 -7
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +37 -36
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +136 -34
- data/lib/active_record/connection_adapters/abstract/transaction.rb +163 -68
- data/lib/active_record/connection_adapters/abstract_adapter.rb +197 -129
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +112 -63
- data/lib/active_record/connection_adapters/column.rb +17 -4
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +11 -3
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -57
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +41 -10
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +79 -46
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +97 -101
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +14 -33
- data/lib/active_record/connection_adapters/pool_config.rb +14 -13
- data/lib/active_record/connection_adapters/postgresql/column.rb +4 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +98 -44
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +10 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +79 -68
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -4
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +9 -17
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +44 -41
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +69 -32
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +155 -75
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +104 -121
- data/lib/active_record/connection_adapters/schema_cache.rb +126 -133
- data/lib/active_record/connection_adapters/sqlite3/column.rb +14 -1
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +91 -95
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +57 -54
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +13 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +43 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +38 -15
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +231 -111
- data/lib/active_record/connection_adapters/statement_pool.rb +4 -2
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +40 -69
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +19 -65
- data/lib/active_record/connection_adapters.rb +66 -0
- data/lib/active_record/connection_handling.rb +88 -46
- data/lib/active_record/core.rb +142 -58
- data/lib/active_record/counter_cache.rb +52 -18
- data/lib/active_record/database_configurations/connection_url_resolver.rb +9 -2
- data/lib/active_record/database_configurations/database_config.rb +28 -5
- data/lib/active_record/database_configurations/hash_config.rb +103 -41
- data/lib/active_record/database_configurations/url_config.rb +30 -1
- data/lib/active_record/database_configurations.rb +8 -4
- data/lib/active_record/delegated_type.rb +43 -19
- data/lib/active_record/dynamic_matchers.rb +56 -71
- data/lib/active_record/encryption/config.rb +3 -1
- data/lib/active_record/encryption/encryptable_record.rb +12 -12
- data/lib/active_record/encryption/encrypted_attribute_type.rb +35 -6
- data/lib/active_record/encryption/encryptor.rb +58 -22
- data/lib/active_record/encryption/extended_deterministic_queries.rb +4 -2
- 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 +4 -0
- data/lib/active_record/encryption/null_encryptor.rb +4 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
- data/lib/active_record/encryption/scheme.rb +9 -2
- data/lib/active_record/enum.rb +57 -36
- data/lib/active_record/errors.rb +76 -26
- data/lib/active_record/explain.rb +14 -25
- data/lib/active_record/explain_registry.rb +51 -2
- data/lib/active_record/filter_attribute_handler.rb +73 -0
- data/lib/active_record/fixture_set/table_row.rb +19 -2
- data/lib/active_record/fixtures.rb +39 -35
- data/lib/active_record/future_result.rb +21 -13
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +5 -3
- data/lib/active_record/insert_all.rb +28 -20
- data/lib/active_record/integration.rb +4 -1
- data/lib/active_record/internal_metadata.rb +48 -34
- data/lib/active_record/locking/optimistic.rb +15 -7
- data/lib/active_record/locking/pessimistic.rb +5 -0
- data/lib/active_record/log_subscriber.rb +3 -34
- data/lib/active_record/message_pack.rb +1 -1
- data/lib/active_record/middleware/shard_selector.rb +34 -17
- data/lib/active_record/migration/command_recorder.rb +46 -14
- data/lib/active_record/migration/compatibility.rb +40 -25
- data/lib/active_record/migration/default_schema_versions_formatter.rb +30 -0
- data/lib/active_record/migration/default_strategy.rb +4 -5
- data/lib/active_record/migration/pending_migration_connection.rb +2 -2
- data/lib/active_record/migration.rb +119 -103
- data/lib/active_record/model_schema.rb +66 -78
- data/lib/active_record/nested_attributes.rb +17 -9
- data/lib/active_record/persistence.rb +161 -454
- data/lib/active_record/query_cache.rb +33 -15
- data/lib/active_record/query_logs.rb +106 -39
- data/lib/active_record/query_logs_formatter.rb +17 -28
- data/lib/active_record/querying.rb +28 -16
- data/lib/active_record/railtie.rb +61 -74
- data/lib/active_record/railties/controller_runtime.rb +19 -5
- data/lib/active_record/railties/databases.rake +64 -78
- data/lib/active_record/railties/job_checkpoints.rb +15 -0
- data/lib/active_record/railties/job_runtime.rb +10 -11
- data/lib/active_record/reflection.rb +147 -53
- data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
- data/lib/active_record/relation/batches.rb +153 -73
- data/lib/active_record/relation/calculations.rb +146 -96
- data/lib/active_record/relation/delegation.rb +30 -23
- data/lib/active_record/relation/finder_methods.rb +64 -34
- data/lib/active_record/relation/merger.rb +12 -14
- data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +19 -11
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +8 -8
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +4 -3
- data/lib/active_record/relation/predicate_builder.rb +25 -10
- data/lib/active_record/relation/query_attribute.rb +4 -2
- data/lib/active_record/relation/query_methods.rb +351 -124
- data/lib/active_record/relation/spawn_methods.rb +9 -25
- data/lib/active_record/relation/where_clause.rb +17 -30
- data/lib/active_record/relation.rb +590 -124
- data/lib/active_record/result.rb +131 -59
- data/lib/active_record/runtime_registry.rb +44 -21
- data/lib/active_record/sanitization.rb +33 -25
- data/lib/active_record/schema.rb +8 -6
- data/lib/active_record/schema_dumper.rb +66 -31
- data/lib/active_record/schema_migration.rb +31 -14
- data/lib/active_record/scoping/named.rb +6 -2
- data/lib/active_record/scoping.rb +0 -1
- data/lib/active_record/secure_token.rb +3 -3
- data/lib/active_record/signed_id.rb +68 -20
- data/lib/active_record/statement_cache.rb +29 -25
- data/lib/active_record/store.rb +51 -22
- data/lib/active_record/structured_event_subscriber.rb +85 -0
- data/lib/active_record/table_metadata.rb +7 -33
- data/lib/active_record/tasks/abstract_tasks.rb +76 -0
- data/lib/active_record/tasks/database_tasks.rb +118 -90
- data/lib/active_record/tasks/mysql_database_tasks.rb +3 -42
- data/lib/active_record/tasks/postgresql_database_tasks.rb +14 -40
- data/lib/active_record/tasks/sqlite_database_tasks.rb +17 -28
- data/lib/active_record/test_databases.rb +14 -4
- data/lib/active_record/test_fixtures.rb +123 -89
- data/lib/active_record/testing/query_assertions.rb +127 -0
- data/lib/active_record/timestamp.rb +6 -4
- data/lib/active_record/token_for.rb +22 -12
- data/lib/active_record/touch_later.rb +1 -1
- data/lib/active_record/transaction.rb +129 -0
- data/lib/active_record/transactions.rb +97 -18
- data/lib/active_record/translation.rb +0 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +2 -1
- data/lib/active_record/type/internal/timezone.rb +7 -0
- data/lib/active_record/type/json.rb +15 -2
- data/lib/active_record/type/serialized.rb +12 -7
- data/lib/active_record/type/type_map.rb +1 -1
- data/lib/active_record/type_caster/connection.rb +5 -4
- data/lib/active_record/validations/associated.rb +10 -4
- data/lib/active_record/validations/uniqueness.rb +23 -18
- data/lib/active_record/validations.rb +4 -1
- data/lib/active_record.rb +203 -59
- data/lib/arel/alias_predication.rb +3 -1
- data/lib/arel/collectors/bind.rb +4 -2
- data/lib/arel/collectors/composite.rb +7 -0
- data/lib/arel/collectors/sql_string.rb +2 -2
- data/lib/arel/collectors/substitute_binds.rb +3 -3
- data/lib/arel/crud.rb +8 -11
- data/lib/arel/delete_manager.rb +5 -0
- data/lib/arel/nodes/binary.rb +1 -7
- data/lib/arel/nodes/bound_sql_literal.rb +9 -5
- data/lib/arel/nodes/count.rb +2 -2
- data/lib/arel/nodes/delete_statement.rb +4 -2
- data/lib/arel/nodes/function.rb +4 -10
- data/lib/arel/nodes/named_function.rb +2 -2
- data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
- data/lib/arel/nodes/node.rb +6 -5
- data/lib/arel/nodes/sql_literal.rb +8 -1
- data/lib/arel/nodes/update_statement.rb +4 -2
- data/lib/arel/nodes.rb +2 -4
- data/lib/arel/predications.rb +1 -1
- data/lib/arel/select_manager.rb +14 -5
- data/lib/arel/table.rb +3 -7
- data/lib/arel/tree_manager.rb +3 -2
- data/lib/arel/update_manager.rb +7 -1
- data/lib/arel/visitors/dot.rb +3 -3
- data/lib/arel/visitors/mysql.rb +9 -4
- data/lib/arel/visitors/postgresql.rb +56 -12
- data/lib/arel/visitors/sqlite.rb +80 -8
- data/lib/arel/visitors/to_sql.rb +34 -37
- data/lib/arel.rb +10 -4
- data/lib/rails/generators/active_record/application_record/USAGE +1 -1
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
- metadata +23 -14
- data/lib/active_record/explain_subscriber.rb +0 -34
- data/lib/active_record/normalization.rb +0 -167
- data/lib/active_record/relation/record_fetch_warning.rb +0 -49
|
@@ -17,7 +17,7 @@ module ActiveRecord
|
|
|
17
17
|
:options_include_default?, :supports_indexes_in_create?, :use_foreign_keys?,
|
|
18
18
|
:quoted_columns_for_index, :supports_partial_index?, :supports_check_constraints?,
|
|
19
19
|
:supports_index_include?, :supports_exclusion_constraints?, :supports_unique_constraints?,
|
|
20
|
-
:supports_nulls_not_distinct?,
|
|
20
|
+
:supports_nulls_not_distinct?, :lookup_cast_type,
|
|
21
21
|
to: :@conn, private: true
|
|
22
22
|
|
|
23
23
|
private
|
|
@@ -28,6 +28,7 @@ module ActiveRecord
|
|
|
28
28
|
sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(" ")
|
|
29
29
|
sql << o.check_constraint_adds.map { |con| visit_AddCheckConstraint con }.join(" ")
|
|
30
30
|
sql << o.check_constraint_drops.map { |con| visit_DropCheckConstraint con }.join(" ")
|
|
31
|
+
sql << o.constraint_drops.map { |con| visit_DropConstraint con }.join(" ")
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
def visit_ColumnDefinition(o)
|
|
@@ -96,9 +97,11 @@ module ActiveRecord
|
|
|
96
97
|
"ADD #{accept(o)}"
|
|
97
98
|
end
|
|
98
99
|
|
|
99
|
-
def
|
|
100
|
+
def visit_DropConstraint(name)
|
|
100
101
|
"DROP CONSTRAINT #{quote_column_name(name)}"
|
|
101
102
|
end
|
|
103
|
+
alias :visit_DropForeignKey :visit_DropConstraint
|
|
104
|
+
alias :visit_DropCheckConstraint :visit_DropConstraint
|
|
102
105
|
|
|
103
106
|
def visit_CreateIndexDefinition(o)
|
|
104
107
|
index = o.index
|
|
@@ -127,10 +130,6 @@ module ActiveRecord
|
|
|
127
130
|
"ADD #{accept(o)}"
|
|
128
131
|
end
|
|
129
132
|
|
|
130
|
-
def visit_DropCheckConstraint(name)
|
|
131
|
-
"DROP CONSTRAINT #{quote_column_name(name)}"
|
|
132
|
-
end
|
|
133
|
-
|
|
134
133
|
def quoted_columns(o)
|
|
135
134
|
String === o.columns ? o.columns : quoted_columns_for_index(o.columns, o.column_options)
|
|
136
135
|
end
|
|
@@ -149,7 +148,7 @@ module ActiveRecord
|
|
|
149
148
|
end
|
|
150
149
|
|
|
151
150
|
def add_column_options!(sql, options)
|
|
152
|
-
sql << " DEFAULT #{
|
|
151
|
+
sql << " DEFAULT #{quote_default_expression_for_column_definition(options[:default], options[:column])}" if options_include_default?(options)
|
|
153
152
|
# must explicitly check for :null to allow change_column to work on migrations
|
|
154
153
|
if options[:null] == false
|
|
155
154
|
sql << " NOT NULL"
|
|
@@ -163,6 +162,11 @@ module ActiveRecord
|
|
|
163
162
|
sql
|
|
164
163
|
end
|
|
165
164
|
|
|
165
|
+
def quote_default_expression_for_column_definition(default, column_definition)
|
|
166
|
+
column_definition.cast_type = lookup_cast_type(column_definition.sql_type)
|
|
167
|
+
quote_default_expression(default, column_definition)
|
|
168
|
+
end
|
|
169
|
+
|
|
166
170
|
def to_sql(sql)
|
|
167
171
|
sql = sql.to_sql if sql.respond_to?(:to_sql)
|
|
168
172
|
sql
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
3
|
module ActiveRecord
|
|
5
4
|
module ConnectionAdapters # :nodoc:
|
|
6
5
|
# Abstract representation of an index definition on a table. Instances of
|
|
@@ -76,7 +75,7 @@ module ActiveRecord
|
|
|
76
75
|
# are typically created by methods in TableDefinition, and added to the
|
|
77
76
|
# +columns+ attribute of said TableDefinition object, in order to be used
|
|
78
77
|
# for generating a number of table creation or table changing SQL statements.
|
|
79
|
-
ColumnDefinition = Struct.new(:name, :type, :options, :sql_type) do # :nodoc:
|
|
78
|
+
ColumnDefinition = Struct.new(:name, :type, :options, :sql_type, :cast_type) do # :nodoc:
|
|
80
79
|
self::OPTION_NAMES = [
|
|
81
80
|
:limit,
|
|
82
81
|
:precision,
|
|
@@ -109,6 +108,10 @@ module ActiveRecord
|
|
|
109
108
|
def aliased_types(name, fallback)
|
|
110
109
|
"timestamp" == name ? :datetime : fallback
|
|
111
110
|
end
|
|
111
|
+
|
|
112
|
+
def fetch_cast_type(connection)
|
|
113
|
+
cast_type
|
|
114
|
+
end
|
|
112
115
|
end
|
|
113
116
|
|
|
114
117
|
AddColumnDefinition = Struct.new(:column) # :nodoc:
|
|
@@ -160,6 +163,8 @@ module ActiveRecord
|
|
|
160
163
|
end
|
|
161
164
|
|
|
162
165
|
def defined_for?(to_table: nil, validate: nil, **options)
|
|
166
|
+
options = options.slice(*self.options.keys)
|
|
167
|
+
|
|
163
168
|
(to_table.nil? || to_table.to_s == self.to_table) &&
|
|
164
169
|
(validate.nil? || validate == self.options.fetch(:validate, validate)) &&
|
|
165
170
|
options.all? { |k, v| Array(self.options[k]).map(&:to_s) == Array(v).map(&:to_s) }
|
|
@@ -186,6 +191,8 @@ module ActiveRecord
|
|
|
186
191
|
end
|
|
187
192
|
|
|
188
193
|
def defined_for?(name:, expression: nil, validate: nil, **options)
|
|
194
|
+
options = options.slice(*self.options.keys)
|
|
195
|
+
|
|
189
196
|
self.name == name.to_s &&
|
|
190
197
|
(validate.nil? || validate == self.options.fetch(:validate, validate)) &&
|
|
191
198
|
options.all? { |k, v| self.options[k].to_s == v.to_s }
|
|
@@ -300,44 +307,32 @@ module ActiveRecord
|
|
|
300
307
|
module ColumnMethods
|
|
301
308
|
extend ActiveSupport::Concern
|
|
302
309
|
|
|
303
|
-
# Appends a primary key definition to the table definition.
|
|
304
|
-
# Can be called multiple times, but this is probably not a good idea.
|
|
305
|
-
def primary_key(name, type = :primary_key, **options)
|
|
306
|
-
column(name, type, **options.merge(primary_key: true))
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
##
|
|
310
|
-
# :method: column
|
|
311
|
-
# :call-seq: column(name, type, **options)
|
|
312
|
-
#
|
|
313
|
-
# Appends a column or columns of a specified type.
|
|
314
|
-
#
|
|
315
|
-
# t.string(:goat)
|
|
316
|
-
# t.string(:goat, :sheep)
|
|
317
|
-
#
|
|
318
|
-
# See TableDefinition#column
|
|
319
|
-
|
|
320
|
-
included do
|
|
321
|
-
define_column_methods :bigint, :binary, :boolean, :date, :datetime, :decimal,
|
|
322
|
-
:float, :integer, :json, :string, :text, :time, :timestamp, :virtual
|
|
323
|
-
|
|
324
|
-
alias :blob :binary
|
|
325
|
-
alias :numeric :decimal
|
|
326
|
-
end
|
|
327
|
-
|
|
328
310
|
class_methods do
|
|
329
|
-
|
|
330
|
-
column_types
|
|
331
|
-
|
|
311
|
+
private
|
|
312
|
+
def define_column_methods(*column_types) # :nodoc:
|
|
313
|
+
column_types.each do |column_type|
|
|
314
|
+
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
332
315
|
def #{column_type}(*names, **options)
|
|
333
316
|
raise ArgumentError, "Missing column name(s) for #{column_type}" if names.empty?
|
|
334
317
|
names.each { |name| column(name, :#{column_type}, **options) }
|
|
335
318
|
end
|
|
336
|
-
|
|
319
|
+
RUBY
|
|
320
|
+
end
|
|
337
321
|
end
|
|
338
|
-
end
|
|
339
|
-
private :define_column_methods
|
|
340
322
|
end
|
|
323
|
+
extend ClassMethods
|
|
324
|
+
|
|
325
|
+
# Appends a primary key definition to the table definition.
|
|
326
|
+
# Can be called multiple times, but this is probably not a good idea.
|
|
327
|
+
def primary_key(name, type = :primary_key, **options)
|
|
328
|
+
column(name, type, **options, primary_key: true)
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
define_column_methods :bigint, :binary, :boolean, :date, :datetime, :decimal,
|
|
332
|
+
:float, :integer, :json, :string, :text, :time, :timestamp, :virtual
|
|
333
|
+
|
|
334
|
+
alias :blob :binary
|
|
335
|
+
alias :numeric :decimal
|
|
341
336
|
end
|
|
342
337
|
|
|
343
338
|
# = Active Record Connection Adapters \Table \Definition
|
|
@@ -348,7 +343,7 @@ module ActiveRecord
|
|
|
348
343
|
# Inside migration files, the +t+ object in {create_table}[rdoc-ref:SchemaStatements#create_table]
|
|
349
344
|
# is actually of this type:
|
|
350
345
|
#
|
|
351
|
-
# class SomeMigration < ActiveRecord::Migration[
|
|
346
|
+
# class SomeMigration < ActiveRecord::Migration[8.1]
|
|
352
347
|
# def up
|
|
353
348
|
# create_table :foo do |t|
|
|
354
349
|
# puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition"
|
|
@@ -431,7 +426,7 @@ module ActiveRecord
|
|
|
431
426
|
#
|
|
432
427
|
# == Examples
|
|
433
428
|
#
|
|
434
|
-
# # Assuming
|
|
429
|
+
# # Assuming `td` is an instance of TableDefinition
|
|
435
430
|
# td.column(:granted, :boolean, index: true)
|
|
436
431
|
#
|
|
437
432
|
# == Short-hand examples
|
|
@@ -622,6 +617,7 @@ module ActiveRecord
|
|
|
622
617
|
attr_reader :adds
|
|
623
618
|
attr_reader :foreign_key_adds, :foreign_key_drops
|
|
624
619
|
attr_reader :check_constraint_adds, :check_constraint_drops
|
|
620
|
+
attr_reader :constraint_drops
|
|
625
621
|
|
|
626
622
|
def initialize(td)
|
|
627
623
|
@td = td
|
|
@@ -630,6 +626,7 @@ module ActiveRecord
|
|
|
630
626
|
@foreign_key_drops = []
|
|
631
627
|
@check_constraint_adds = []
|
|
632
628
|
@check_constraint_drops = []
|
|
629
|
+
@constraint_drops = []
|
|
633
630
|
end
|
|
634
631
|
|
|
635
632
|
def name; @td.name; end
|
|
@@ -650,6 +647,10 @@ module ActiveRecord
|
|
|
650
647
|
@check_constraint_drops << constraint_name
|
|
651
648
|
end
|
|
652
649
|
|
|
650
|
+
def drop_constraint(constraint_name)
|
|
651
|
+
@constraint_drops << constraint_name
|
|
652
|
+
end
|
|
653
|
+
|
|
653
654
|
def add_column(name, type, **options)
|
|
654
655
|
name = name.to_s
|
|
655
656
|
type = type.to_sym
|
|
@@ -756,7 +757,7 @@ module ActiveRecord
|
|
|
756
757
|
# end
|
|
757
758
|
#
|
|
758
759
|
# See {connection.index_exists?}[rdoc-ref:SchemaStatements#index_exists?]
|
|
759
|
-
def index_exists?(column_name, **options)
|
|
760
|
+
def index_exists?(column_name = nil, **options)
|
|
760
761
|
@base.index_exists?(name, column_name, **options)
|
|
761
762
|
end
|
|
762
763
|
|
|
@@ -85,7 +85,8 @@ module ActiveRecord
|
|
|
85
85
|
|
|
86
86
|
def schema_default(column)
|
|
87
87
|
return unless column.has_default?
|
|
88
|
-
|
|
88
|
+
# TODO: Remove fetch_cast_type and the need for connection after we release 8.1.
|
|
89
|
+
type = column.fetch_cast_type(@connection)
|
|
89
90
|
default = type.deserialize(column.default)
|
|
90
91
|
if default.nil?
|
|
91
92
|
schema_expression(column)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "active_support/core_ext/string/access"
|
|
4
|
+
require "active_support/core_ext/string/filters"
|
|
4
5
|
require "openssl"
|
|
5
6
|
|
|
6
7
|
module ActiveRecord
|
|
@@ -99,7 +100,7 @@ module ActiveRecord
|
|
|
99
100
|
# # Check a valid index exists (PostgreSQL only)
|
|
100
101
|
# index_exists?(:suppliers, :company_id, valid: true)
|
|
101
102
|
#
|
|
102
|
-
def index_exists?(table_name, column_name, **options)
|
|
103
|
+
def index_exists?(table_name, column_name = nil, **options)
|
|
103
104
|
indexes(table_name).any? { |i| i.defined_for?(column_name, **options) }
|
|
104
105
|
end
|
|
105
106
|
|
|
@@ -186,6 +187,9 @@ module ActiveRecord
|
|
|
186
187
|
# Join tables for {ActiveRecord::Base.has_and_belongs_to_many}[rdoc-ref:Associations::ClassMethods#has_and_belongs_to_many] should set it to false.
|
|
187
188
|
#
|
|
188
189
|
# A Symbol can be used to specify the type of the generated primary key column.
|
|
190
|
+
#
|
|
191
|
+
# A Hash can be used to specify the generated primary key column creation options.
|
|
192
|
+
# See {add_column}[rdoc-ref:ConnectionAdapters::SchemaStatements#add_column] for available options.
|
|
189
193
|
# [<tt>:primary_key</tt>]
|
|
190
194
|
# The name of the primary key, if one is to be added automatically.
|
|
191
195
|
# Defaults to +id+. If <tt>:id</tt> is false, then this option is ignored.
|
|
@@ -293,6 +297,11 @@ module ActiveRecord
|
|
|
293
297
|
def create_table(table_name, id: :primary_key, primary_key: nil, force: nil, **options, &block)
|
|
294
298
|
validate_create_table_options!(options)
|
|
295
299
|
validate_table_length!(table_name) unless options[:_uses_legacy_table_name]
|
|
300
|
+
|
|
301
|
+
if force && options.key?(:if_not_exists)
|
|
302
|
+
raise ArgumentError, "Options `:force` and `:if_not_exists` cannot be used simultaneously."
|
|
303
|
+
end
|
|
304
|
+
|
|
296
305
|
td = build_create_table_definition(table_name, id: id, primary_key: primary_key, force: force, **options, &block)
|
|
297
306
|
|
|
298
307
|
if force
|
|
@@ -340,11 +349,22 @@ module ActiveRecord
|
|
|
340
349
|
# # Creates a table called 'assemblies_parts' with no id.
|
|
341
350
|
# create_join_table(:assemblies, :parts)
|
|
342
351
|
#
|
|
352
|
+
# # Creates a table called 'paper_boxes_papers' with no id.
|
|
353
|
+
# create_join_table('papers', 'paper_boxes')
|
|
354
|
+
#
|
|
355
|
+
# A duplicate prefix is combined into a single prefix. This is useful for
|
|
356
|
+
# namespaced models like Music::Artist and Music::Record:
|
|
357
|
+
#
|
|
358
|
+
# # Creates a table called 'music_artists_records' with no id.
|
|
359
|
+
# create_join_table('music_artists', 'music_records')
|
|
360
|
+
#
|
|
361
|
+
# See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference]
|
|
362
|
+
# for details of the options you can use in +column_options+. +column_options+
|
|
363
|
+
# will be applied to both columns.
|
|
364
|
+
#
|
|
343
365
|
# You can pass an +options+ hash which can include the following keys:
|
|
344
366
|
# [<tt>:table_name</tt>]
|
|
345
367
|
# Sets the table name, overriding the default.
|
|
346
|
-
# [<tt>:column_options</tt>]
|
|
347
|
-
# Any extra options you want appended to the columns definition.
|
|
348
368
|
# [<tt>:options</tt>]
|
|
349
369
|
# Any extra options you want appended to the table definition.
|
|
350
370
|
# [<tt>:temporary</tt>]
|
|
@@ -361,6 +381,19 @@ module ActiveRecord
|
|
|
361
381
|
# t.index :category_id
|
|
362
382
|
# end
|
|
363
383
|
#
|
|
384
|
+
# ====== Add foreign keys with delete cascade
|
|
385
|
+
#
|
|
386
|
+
# create_join_table(:assemblies, :parts, column_options: { foreign_key: { on_delete: :cascade } })
|
|
387
|
+
#
|
|
388
|
+
# generates:
|
|
389
|
+
#
|
|
390
|
+
# CREATE TABLE assemblies_parts (
|
|
391
|
+
# assembly_id bigint NOT NULL,
|
|
392
|
+
# part_id bigint NOT NULL,
|
|
393
|
+
# CONSTRAINT fk_rails_0d8a572d89 FOREIGN KEY ("assembly_id") REFERENCES "assemblies" ("id") ON DELETE CASCADE,
|
|
394
|
+
# CONSTRAINT fk_rails_ec7b48402b FOREIGN KEY ("part_id") REFERENCES "parts" ("id") ON DELETE CASCADE
|
|
395
|
+
# )
|
|
396
|
+
#
|
|
364
397
|
# ====== Add a backend specific option to the generated SQL (MySQL)
|
|
365
398
|
#
|
|
366
399
|
# create_join_table(:assemblies, :parts, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8')
|
|
@@ -511,7 +544,7 @@ module ActiveRecord
|
|
|
511
544
|
raise NotImplementedError, "rename_table is not implemented"
|
|
512
545
|
end
|
|
513
546
|
|
|
514
|
-
# Drops a table from the database.
|
|
547
|
+
# Drops a table or tables from the database.
|
|
515
548
|
#
|
|
516
549
|
# [<tt>:force</tt>]
|
|
517
550
|
# Set to +:cascade+ to drop dependent objects as well.
|
|
@@ -522,17 +555,19 @@ module ActiveRecord
|
|
|
522
555
|
#
|
|
523
556
|
# Although this command ignores most +options+ and the block if one is given,
|
|
524
557
|
# it can be helpful to provide these in a migration's +change+ method so it can be reverted.
|
|
525
|
-
# In that case, +options+ and the block will be used by #create_table.
|
|
526
|
-
def drop_table(
|
|
527
|
-
|
|
528
|
-
|
|
558
|
+
# In that case, +options+ and the block will be used by #create_table except if you provide more than one table which is not supported.
|
|
559
|
+
def drop_table(*table_names, **options)
|
|
560
|
+
table_names.each do |table_name|
|
|
561
|
+
schema_cache.clear_data_source_cache!(table_name.to_s)
|
|
562
|
+
execute "DROP TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}"
|
|
563
|
+
end
|
|
529
564
|
end
|
|
530
565
|
|
|
531
566
|
# Add a new +type+ column named +column_name+ to +table_name+.
|
|
532
567
|
#
|
|
533
568
|
# See {ActiveRecord::ConnectionAdapters::TableDefinition.column}[rdoc-ref:ActiveRecord::ConnectionAdapters::TableDefinition#column].
|
|
534
569
|
#
|
|
535
|
-
# The +type+ parameter is normally one of the
|
|
570
|
+
# The +type+ parameter is normally one of the migration's native types,
|
|
536
571
|
# which is one of the following:
|
|
537
572
|
# <tt>:primary_key</tt>, <tt>:string</tt>, <tt>:text</tt>,
|
|
538
573
|
# <tt>:integer</tt>, <tt>:bigint</tt>, <tt>:float</tt>, <tt>:decimal</tt>, <tt>:numeric</tt>,
|
|
@@ -677,7 +712,7 @@ module ActiveRecord
|
|
|
677
712
|
#
|
|
678
713
|
# If the options provided include an +if_exists+ key, it will be used to check if the
|
|
679
714
|
# column does not exist. This will silently ignore the migration rather than raising
|
|
680
|
-
# if the column was already
|
|
715
|
+
# if the column was already removed.
|
|
681
716
|
#
|
|
682
717
|
# remove_column(:suppliers, :qualification, if_exists: true)
|
|
683
718
|
def remove_column(table_name, column_name, type = nil, **options)
|
|
@@ -839,6 +874,16 @@ module ActiveRecord
|
|
|
839
874
|
#
|
|
840
875
|
# Note: only supported by PostgreSQL.
|
|
841
876
|
#
|
|
877
|
+
# ====== Creating an index where NULLs are treated equally
|
|
878
|
+
#
|
|
879
|
+
# add_index(:people, :last_name, nulls_not_distinct: true)
|
|
880
|
+
#
|
|
881
|
+
# generates:
|
|
882
|
+
#
|
|
883
|
+
# CREATE INDEX index_people_on_last_name ON people (last_name) NULLS NOT DISTINCT
|
|
884
|
+
#
|
|
885
|
+
# Note: only supported by PostgreSQL version 15.0.0 and greater.
|
|
886
|
+
#
|
|
842
887
|
# ====== Creating an index with a specific method
|
|
843
888
|
#
|
|
844
889
|
# add_index(:developers, :name, using: 'btree')
|
|
@@ -876,13 +921,29 @@ module ActiveRecord
|
|
|
876
921
|
# ====== Creating an index with a specific algorithm
|
|
877
922
|
#
|
|
878
923
|
# add_index(:developers, :name, algorithm: :concurrently)
|
|
879
|
-
# # CREATE INDEX CONCURRENTLY developers_on_name on developers (name)
|
|
924
|
+
# # CREATE INDEX CONCURRENTLY developers_on_name on developers (name) -- PostgreSQL
|
|
880
925
|
#
|
|
881
|
-
#
|
|
926
|
+
# add_index(:developers, :name, algorithm: :inplace)
|
|
927
|
+
# # CREATE INDEX `index_developers_on_name` ON `developers` (`name`) ALGORITHM = INPLACE -- MySQL
|
|
928
|
+
#
|
|
929
|
+
# Note: only supported by PostgreSQL and MySQL.
|
|
882
930
|
#
|
|
883
931
|
# Concurrently adding an index is not supported in a transaction.
|
|
884
932
|
#
|
|
885
933
|
# For more information see the {"Transactional Migrations" section}[rdoc-ref:Migration].
|
|
934
|
+
#
|
|
935
|
+
# ====== Creating an index that is not used by queries
|
|
936
|
+
#
|
|
937
|
+
# add_index(:developers, :name, enabled: false)
|
|
938
|
+
#
|
|
939
|
+
# generates:
|
|
940
|
+
#
|
|
941
|
+
# CREATE INDEX index_developers_on_name ON developers (name) INVISIBLE -- MySQL
|
|
942
|
+
#
|
|
943
|
+
# CREATE INDEX index_developers_on_name ON developers (name) IGNORED -- MariaDB
|
|
944
|
+
#
|
|
945
|
+
# Note: only supported by MySQL version 8.0.0 and greater, and MariaDB version 10.6.0 and greater.
|
|
946
|
+
#
|
|
886
947
|
def add_index(table_name, column_name, **options)
|
|
887
948
|
create_index = build_create_index_definition(table_name, column_name, **options)
|
|
888
949
|
execute schema_creation.accept(create_index)
|
|
@@ -1143,9 +1204,10 @@ module ActiveRecord
|
|
|
1143
1204
|
# +:deferred+ or +:immediate+ to specify the default behavior. Defaults to +false+.
|
|
1144
1205
|
def add_foreign_key(from_table, to_table, **options)
|
|
1145
1206
|
return unless use_foreign_keys?
|
|
1146
|
-
return if options[:if_not_exists] == true && foreign_key_exists?(from_table, to_table, **options.slice(:column))
|
|
1147
1207
|
|
|
1148
1208
|
options = foreign_key_options(from_table, to_table, options)
|
|
1209
|
+
return if options[:if_not_exists] == true && foreign_key_exists?(from_table, to_table, **options.slice(:column, :primary_key))
|
|
1210
|
+
|
|
1149
1211
|
at = create_alter_table from_table
|
|
1150
1212
|
at.add_foreign_key to_table, options
|
|
1151
1213
|
|
|
@@ -1184,7 +1246,7 @@ module ActiveRecord
|
|
|
1184
1246
|
# The name of the table that contains the referenced primary key.
|
|
1185
1247
|
def remove_foreign_key(from_table, to_table = nil, **options)
|
|
1186
1248
|
return unless use_foreign_keys?
|
|
1187
|
-
return if options.delete(:if_exists) == true && !foreign_key_exists?(from_table, to_table)
|
|
1249
|
+
return if options.delete(:if_exists) == true && !foreign_key_exists?(from_table, to_table, **options.slice(:column))
|
|
1188
1250
|
|
|
1189
1251
|
fk_name_to_delete = foreign_key_for!(from_table, to_table: to_table, **options).name
|
|
1190
1252
|
|
|
@@ -1305,7 +1367,6 @@ module ActiveRecord
|
|
|
1305
1367
|
execute schema_creation.accept(at)
|
|
1306
1368
|
end
|
|
1307
1369
|
|
|
1308
|
-
|
|
1309
1370
|
# Checks to see if a check constraint exists on a table for a given check constraint definition.
|
|
1310
1371
|
#
|
|
1311
1372
|
# check_constraint_exists?(:products, name: "price_check")
|
|
@@ -1317,8 +1378,15 @@ module ActiveRecord
|
|
|
1317
1378
|
check_constraint_for(table_name, **options).present?
|
|
1318
1379
|
end
|
|
1319
1380
|
|
|
1320
|
-
def
|
|
1321
|
-
|
|
1381
|
+
def remove_constraint(table_name, constraint_name) # :nodoc:
|
|
1382
|
+
at = create_alter_table(table_name)
|
|
1383
|
+
at.drop_constraint(constraint_name)
|
|
1384
|
+
|
|
1385
|
+
execute schema_creation.accept(at)
|
|
1386
|
+
end
|
|
1387
|
+
|
|
1388
|
+
def dump_schema_versions # :nodoc:
|
|
1389
|
+
versions = pool.schema_migration.versions
|
|
1322
1390
|
insert_versions_sql(versions) if versions.any?
|
|
1323
1391
|
end
|
|
1324
1392
|
|
|
@@ -1328,8 +1396,9 @@ module ActiveRecord
|
|
|
1328
1396
|
|
|
1329
1397
|
def assume_migrated_upto_version(version)
|
|
1330
1398
|
version = version.to_i
|
|
1331
|
-
sm_table = quote_table_name(schema_migration.table_name)
|
|
1399
|
+
sm_table = quote_table_name(pool.schema_migration.table_name)
|
|
1332
1400
|
|
|
1401
|
+
migration_context = pool.migration_context
|
|
1333
1402
|
migrated = migration_context.get_all_versions
|
|
1334
1403
|
versions = migration_context.migrations.map(&:version)
|
|
1335
1404
|
|
|
@@ -1438,7 +1507,7 @@ module ActiveRecord
|
|
|
1438
1507
|
end
|
|
1439
1508
|
|
|
1440
1509
|
def add_index_options(table_name, column_name, name: nil, if_not_exists: false, internal: false, **options) # :nodoc:
|
|
1441
|
-
options.assert_valid_keys(
|
|
1510
|
+
options.assert_valid_keys(valid_index_options)
|
|
1442
1511
|
|
|
1443
1512
|
column_names = index_column_names(column_name)
|
|
1444
1513
|
|
|
@@ -1447,7 +1516,7 @@ module ActiveRecord
|
|
|
1447
1516
|
|
|
1448
1517
|
validate_index_length!(table_name, index_name, internal)
|
|
1449
1518
|
|
|
1450
|
-
index =
|
|
1519
|
+
index = create_index_definition(
|
|
1451
1520
|
table_name, index_name,
|
|
1452
1521
|
options[:unique],
|
|
1453
1522
|
column_names,
|
|
@@ -1502,6 +1571,20 @@ module ActiveRecord
|
|
|
1502
1571
|
raise NotImplementedError, "#{self.class} does not support changing column comments"
|
|
1503
1572
|
end
|
|
1504
1573
|
|
|
1574
|
+
# Enables an index to be used by queries.
|
|
1575
|
+
#
|
|
1576
|
+
# enable_index(:users, :email)
|
|
1577
|
+
def enable_index(table_name, index_name)
|
|
1578
|
+
raise NotImplementedError, "#{self.class} does not support enabling indexes"
|
|
1579
|
+
end
|
|
1580
|
+
|
|
1581
|
+
# Prevents an index from being used by queries.
|
|
1582
|
+
#
|
|
1583
|
+
# disable_index(:users, :email)
|
|
1584
|
+
def disable_index(table_name, index_name)
|
|
1585
|
+
raise NotImplementedError, "#{self.class} does not support disabling indexes"
|
|
1586
|
+
end
|
|
1587
|
+
|
|
1505
1588
|
def create_schema_dumper(options) # :nodoc:
|
|
1506
1589
|
SchemaDumper.create(self, options)
|
|
1507
1590
|
end
|
|
@@ -1568,7 +1651,7 @@ module ActiveRecord
|
|
|
1568
1651
|
name = "idx_on_#{Array(column) * '_'}"
|
|
1569
1652
|
|
|
1570
1653
|
short_limit = max_index_name_size - hashed_identifier.bytesize
|
|
1571
|
-
short_name = name.
|
|
1654
|
+
short_name = name.truncate_bytes(short_limit, omission: nil)
|
|
1572
1655
|
|
|
1573
1656
|
"#{short_name}#{hashed_identifier}"
|
|
1574
1657
|
end
|
|
@@ -1590,6 +1673,10 @@ module ActiveRecord
|
|
|
1590
1673
|
end
|
|
1591
1674
|
end
|
|
1592
1675
|
|
|
1676
|
+
def valid_index_options
|
|
1677
|
+
[:unique, :length, :order, :opclass, :where, :type, :using, :comment, :algorithm, :include, :nulls_not_distinct]
|
|
1678
|
+
end
|
|
1679
|
+
|
|
1593
1680
|
def options_for_index_columns(options)
|
|
1594
1681
|
if options.is_a?(Hash)
|
|
1595
1682
|
options.symbolize_keys
|
|
@@ -1666,6 +1753,10 @@ module ActiveRecord
|
|
|
1666
1753
|
TableDefinition.new(self, name, **options)
|
|
1667
1754
|
end
|
|
1668
1755
|
|
|
1756
|
+
def create_index_definition(table_name, name, unique, columns, **options)
|
|
1757
|
+
IndexDefinition.new(table_name, name, unique, columns, **options)
|
|
1758
|
+
end
|
|
1759
|
+
|
|
1669
1760
|
def create_alter_table(name)
|
|
1670
1761
|
AlterTable.new create_table_definition(name)
|
|
1671
1762
|
end
|
|
@@ -1728,7 +1819,20 @@ module ActiveRecord
|
|
|
1728
1819
|
|
|
1729
1820
|
def foreign_key_for(from_table, **options)
|
|
1730
1821
|
return unless use_foreign_keys?
|
|
1731
|
-
|
|
1822
|
+
|
|
1823
|
+
keys = foreign_keys(from_table)
|
|
1824
|
+
|
|
1825
|
+
if options[:_skip_column_match]
|
|
1826
|
+
return keys.find { |fk| fk.defined_for?(**options) }
|
|
1827
|
+
end
|
|
1828
|
+
|
|
1829
|
+
if options[:column].nil?
|
|
1830
|
+
default_column = foreign_key_column_for(options[:to_table], "id")
|
|
1831
|
+
matches = keys.select { |fk| fk.column == default_column }
|
|
1832
|
+
keys = matches if matches.any?
|
|
1833
|
+
end
|
|
1834
|
+
|
|
1835
|
+
keys.find { |fk| fk.defined_for?(**options) }
|
|
1732
1836
|
end
|
|
1733
1837
|
|
|
1734
1838
|
def foreign_key_for!(from_table, to_table: nil, **options)
|
|
@@ -1771,13 +1875,19 @@ module ActiveRecord
|
|
|
1771
1875
|
|
|
1772
1876
|
def validate_index_length!(table_name, new_name, internal = false)
|
|
1773
1877
|
if new_name.length > index_name_length
|
|
1774
|
-
raise ArgumentError,
|
|
1878
|
+
raise ArgumentError, <<~MSG.squish
|
|
1879
|
+
Index name '#{new_name}' on table '#{table_name}' is too long (#{new_name.length} characters); the limit
|
|
1880
|
+
is #{index_name_length} characters
|
|
1881
|
+
MSG
|
|
1775
1882
|
end
|
|
1776
1883
|
end
|
|
1777
1884
|
|
|
1778
1885
|
def validate_table_length!(table_name)
|
|
1779
1886
|
if table_name.length > table_name_length
|
|
1780
|
-
raise ArgumentError,
|
|
1887
|
+
raise ArgumentError, <<~MSG.squish
|
|
1888
|
+
Table name '#{table_name}' is too long (#{table_name.length} characters); the limit is
|
|
1889
|
+
#{table_name_length} characters
|
|
1890
|
+
MSG
|
|
1781
1891
|
end
|
|
1782
1892
|
end
|
|
1783
1893
|
|
|
@@ -1839,16 +1949,8 @@ module ActiveRecord
|
|
|
1839
1949
|
end
|
|
1840
1950
|
|
|
1841
1951
|
def insert_versions_sql(versions)
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
if versions.is_a?(Array)
|
|
1845
|
-
sql = +"INSERT INTO #{sm_table} (version) VALUES\n"
|
|
1846
|
-
sql << versions.reverse.map { |v| "(#{quote(v)})" }.join(",\n")
|
|
1847
|
-
sql << ";"
|
|
1848
|
-
sql
|
|
1849
|
-
else
|
|
1850
|
-
"INSERT INTO #{sm_table} (version) VALUES (#{quote(versions)});"
|
|
1851
|
-
end
|
|
1952
|
+
versions_formatter = ActiveRecord.schema_versions_formatter.new(self)
|
|
1953
|
+
versions_formatter.format(versions)
|
|
1852
1954
|
end
|
|
1853
1955
|
|
|
1854
1956
|
def data_source_sql(name = nil, type: nil)
|