activerecord 8.0.0.beta1 → 8.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +67 -0
- data/lib/active_record/associations/has_many_through_association.rb +7 -1
- data/lib/active_record/attribute_methods/primary_key.rb +2 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +2 -12
- data/lib/active_record/callbacks.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +26 -8
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +6 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +8 -2
- data/lib/active_record/connection_adapters/abstract_adapter.rb +0 -1
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +8 -4
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -4
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +0 -10
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -11
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +4 -8
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +8 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +1 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +0 -2
- data/lib/active_record/connection_adapters.rb +0 -56
- data/lib/active_record/core.rb +14 -11
- data/lib/active_record/enum.rb +54 -72
- data/lib/active_record/fixtures.rb +0 -1
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/locking/optimistic.rb +1 -1
- data/lib/active_record/log_subscriber.rb +5 -11
- data/lib/active_record/marshalling.rb +4 -1
- data/lib/active_record/migration.rb +0 -5
- data/lib/active_record/model_schema.rb +2 -3
- data/lib/active_record/query_cache.rb +0 -4
- data/lib/active_record/query_logs.rb +5 -11
- data/lib/active_record/querying.rb +2 -2
- data/lib/active_record/railtie.rb +1 -24
- data/lib/active_record/railties/databases.rake +1 -1
- data/lib/active_record/reflection.rb +14 -19
- data/lib/active_record/relation/calculations.rb +24 -28
- data/lib/active_record/relation/predicate_builder.rb +8 -0
- data/lib/active_record/relation/query_methods.rb +66 -36
- data/lib/active_record/relation.rb +8 -1
- data/lib/active_record/result.rb +10 -9
- data/lib/active_record/table_metadata.rb +1 -3
- data/lib/active_record/tasks/database_tasks.rb +4 -31
- data/lib/active_record/testing/query_assertions.rb +2 -2
- data/lib/active_record.rb +0 -45
- data/lib/arel/table.rb +3 -7
- data/lib/arel/visitors/sqlite.rb +25 -0
- metadata +9 -10
- data/lib/active_record/relation/record_fetch_warning.rb +0 -52
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c87db8720964fea39e42e8eb013edb1fc3fd47e5964e5d6d6fdbe46295766f02
|
4
|
+
data.tar.gz: c4bf7718e51c5accaad971f57faae94312d5cf81f5cfc4e58e8d4fe138027964
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81389502abf74508e9eb58bcf7c91088bf4c44b858bd121128e801fee6a3a58309e0f455444bbe43faea18f7fe458610ab04ad8286d8e9faebf06ba5198bcba9
|
7
|
+
data.tar.gz: 85de6837aff3ae8a24f177c53e2f3912c6660493bbb4138f75223a2dcb813c7f796444bd4d0196f606d16ce1bde6d3352d30d54279c72bb99910eee7f4183924
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,70 @@
|
|
1
|
+
## Rails 8.0.0.rc1 (October 19, 2024) ##
|
2
|
+
|
3
|
+
* Remove deprecated support to setting `ENV["SCHEMA_CACHE"]`.
|
4
|
+
|
5
|
+
*Rafael Mendonça França*
|
6
|
+
|
7
|
+
* Remove deprecated support to passing a database name to `cache_dump_filename`.
|
8
|
+
|
9
|
+
*Rafael Mendonça França*
|
10
|
+
|
11
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::ConnectionPool#connection`.
|
12
|
+
|
13
|
+
*Rafael Mendonça França*
|
14
|
+
|
15
|
+
* Remove deprecated `config.active_record.sqlite3_deprecated_warning`.
|
16
|
+
|
17
|
+
*Rafael Mendonça França*
|
18
|
+
|
19
|
+
* Remove deprecated `config.active_record.warn_on_records_fetched_greater_than`.
|
20
|
+
|
21
|
+
*Rafael Mendonça França*
|
22
|
+
|
23
|
+
* Remove deprecated support for defining `enum` with keyword arguments.
|
24
|
+
|
25
|
+
*Rafael Mendonça França*
|
26
|
+
|
27
|
+
* Remove deprecated support to finding database adapters that aren't registered to Active Record.
|
28
|
+
|
29
|
+
*Rafael Mendonça França*
|
30
|
+
|
31
|
+
* Remove deprecated `config.active_record.allow_deprecated_singular_associations_name`.
|
32
|
+
|
33
|
+
*Rafael Mendonça França*
|
34
|
+
|
35
|
+
* Remove deprecated `config.active_record.commit_transaction_on_non_local_return`.
|
36
|
+
|
37
|
+
*Rafael Mendonça França*
|
38
|
+
|
39
|
+
* Fix incorrect SQL query when passing an empty hash to `ActiveRecord::Base.insert`.
|
40
|
+
|
41
|
+
*David Stosik*
|
42
|
+
|
43
|
+
* Allow to save records with polymorphic join tables that have `inverse_of`
|
44
|
+
specified.
|
45
|
+
|
46
|
+
*Markus Doits*
|
47
|
+
|
48
|
+
* Fix association scopes applying on the incorrect join when using a polymorphic `has_many through:`.
|
49
|
+
|
50
|
+
*Joshua Young*
|
51
|
+
|
52
|
+
* Allow `ActiveRecord::Base#pluck` to accept hash arguments with symbol and string values.
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
Post.joins(:comments).pluck(:id, comments: :id)
|
56
|
+
Post.joins(:comments).pluck("id", "comments" => "id")
|
57
|
+
```
|
58
|
+
|
59
|
+
*Joshua Young*
|
60
|
+
|
61
|
+
* Make Float distinguish between `float4` and `float8` in PostgreSQL.
|
62
|
+
|
63
|
+
Fixes #52742
|
64
|
+
|
65
|
+
*Ryota Kitazawa*, *Takayuki Nagatomi*
|
66
|
+
|
67
|
+
|
1
68
|
## Rails 8.0.0.beta1 (September 26, 2024) ##
|
2
69
|
|
3
70
|
* Allow `drop_table` to accept an array of table names.
|
@@ -93,7 +93,13 @@ module ActiveRecord
|
|
93
93
|
@through_scope = scope
|
94
94
|
record = super
|
95
95
|
|
96
|
-
inverse =
|
96
|
+
inverse =
|
97
|
+
if source_reflection.polymorphic?
|
98
|
+
source_reflection.polymorphic_inverse_of(record.class)
|
99
|
+
else
|
100
|
+
source_reflection.inverse_of
|
101
|
+
end
|
102
|
+
|
97
103
|
if inverse
|
98
104
|
if inverse.collection?
|
99
105
|
record.send(inverse.name) << build_through_record(record)
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "set"
|
4
|
-
|
5
3
|
module ActiveRecord
|
6
4
|
module AttributeMethods
|
7
5
|
# = Active Record Attribute Methods Primary Key
|
@@ -89,10 +87,9 @@ module ActiveRecord
|
|
89
87
|
@composite_primary_key
|
90
88
|
end
|
91
89
|
|
92
|
-
# Returns a quoted version of the primary key name
|
93
|
-
# SQL statements.
|
90
|
+
# Returns a quoted version of the primary key name.
|
94
91
|
def quoted_primary_key
|
95
|
-
|
92
|
+
adapter_class.quote_column_name(primary_key)
|
96
93
|
end
|
97
94
|
|
98
95
|
def reset_primary_key # :nodoc:
|
@@ -138,7 +135,6 @@ module ActiveRecord
|
|
138
135
|
elsif value
|
139
136
|
-value.to_s
|
140
137
|
end
|
141
|
-
@quoted_primary_key = nil
|
142
138
|
@attributes_builder = nil
|
143
139
|
end
|
144
140
|
|
@@ -148,7 +144,6 @@ module ActiveRecord
|
|
148
144
|
base.class_eval do
|
149
145
|
@primary_key = PRIMARY_KEY_NOT_SET
|
150
146
|
@composite_primary_key = false
|
151
|
-
@quoted_primary_key = nil
|
152
147
|
@attributes_builder = nil
|
153
148
|
end
|
154
149
|
end
|
@@ -28,7 +28,7 @@ module ActiveRecord
|
|
28
28
|
elsif value.respond_to?(:infinite?) && value.infinite?
|
29
29
|
value
|
30
30
|
else
|
31
|
-
|
31
|
+
map(super) { |v| cast(v) }
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -45,23 +45,13 @@ module ActiveRecord
|
|
45
45
|
elsif value.respond_to?(:infinite?) && value.infinite?
|
46
46
|
value
|
47
47
|
else
|
48
|
-
|
48
|
+
map(value) { |v| convert_time_to_time_zone(v) }
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
52
|
def set_time_zone_without_conversion(value)
|
53
53
|
::Time.zone.local_to_utc(value).try(:in_time_zone) if value
|
54
54
|
end
|
55
|
-
|
56
|
-
def map_avoiding_infinite_recursion(value)
|
57
|
-
map(value) do |v|
|
58
|
-
if value.equal?(v)
|
59
|
-
nil
|
60
|
-
else
|
61
|
-
yield(v)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
55
|
end
|
66
56
|
|
67
57
|
extend ActiveSupport::Concern
|
@@ -418,7 +418,7 @@ module ActiveRecord
|
|
418
418
|
|
419
419
|
def destroy # :nodoc:
|
420
420
|
@_destroy_callback_already_called ||= false
|
421
|
-
return if @_destroy_callback_already_called
|
421
|
+
return true if @_destroy_callback_already_called
|
422
422
|
@_destroy_callback_already_called = true
|
423
423
|
_run_destroy_callbacks { super }
|
424
424
|
rescue RecordNotDestroyed => e
|
@@ -183,6 +183,31 @@ module ActiveRecord
|
|
183
183
|
end
|
184
184
|
end
|
185
185
|
|
186
|
+
module ExecutorHooks # :nodoc:
|
187
|
+
class << self
|
188
|
+
def run
|
189
|
+
# noop
|
190
|
+
end
|
191
|
+
|
192
|
+
def complete(_)
|
193
|
+
ActiveRecord::Base.connection_handler.each_connection_pool do |pool|
|
194
|
+
if (connection = pool.active_connection?)
|
195
|
+
transaction = connection.current_transaction
|
196
|
+
if transaction.closed? || !transaction.joinable?
|
197
|
+
pool.release_connection
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
class << self
|
206
|
+
def install_executor_hooks(executor = ActiveSupport::Executor)
|
207
|
+
executor.register_hook(ExecutorHooks)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
186
211
|
include MonitorMixin
|
187
212
|
prepend QueryCache::ConnectionPoolConfiguration
|
188
213
|
include ConnectionAdapters::AbstractPool
|
@@ -291,14 +316,6 @@ module ActiveRecord
|
|
291
316
|
connection_lease.sticky.nil?
|
292
317
|
end
|
293
318
|
|
294
|
-
def connection
|
295
|
-
ActiveRecord.deprecator.warn(<<~MSG)
|
296
|
-
ActiveRecord::ConnectionAdapters::ConnectionPool#connection is deprecated
|
297
|
-
and will be removed in Rails 8.0. Use #lease_connection instead.
|
298
|
-
MSG
|
299
|
-
lease_connection
|
300
|
-
end
|
301
|
-
|
302
319
|
def pin_connection!(lock_thread) # :nodoc:
|
303
320
|
@pinned_connection ||= (connection_lease&.connection || checkout)
|
304
321
|
@pinned_connections_depth += 1
|
@@ -332,6 +349,7 @@ module ActiveRecord
|
|
332
349
|
end
|
333
350
|
|
334
351
|
if @pinned_connection.nil?
|
352
|
+
connection.steal!
|
335
353
|
connection.lock_thread = nil
|
336
354
|
checkin(connection)
|
337
355
|
end
|
@@ -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
|
@@ -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
|
@@ -622,6 +621,7 @@ module ActiveRecord
|
|
622
621
|
attr_reader :adds
|
623
622
|
attr_reader :foreign_key_adds, :foreign_key_drops
|
624
623
|
attr_reader :check_constraint_adds, :check_constraint_drops
|
624
|
+
attr_reader :constraint_drops
|
625
625
|
|
626
626
|
def initialize(td)
|
627
627
|
@td = td
|
@@ -630,6 +630,7 @@ module ActiveRecord
|
|
630
630
|
@foreign_key_drops = []
|
631
631
|
@check_constraint_adds = []
|
632
632
|
@check_constraint_drops = []
|
633
|
+
@constraint_drops = []
|
633
634
|
end
|
634
635
|
|
635
636
|
def name; @td.name; end
|
@@ -650,6 +651,10 @@ module ActiveRecord
|
|
650
651
|
@check_constraint_drops << constraint_name
|
651
652
|
end
|
652
653
|
|
654
|
+
def drop_constraint(constraint_name)
|
655
|
+
@constraint_drops << constraint_name
|
656
|
+
end
|
657
|
+
|
653
658
|
def add_column(name, type, **options)
|
654
659
|
name = name.to_s
|
655
660
|
type = type.to_sym
|
@@ -693,7 +693,7 @@ module ActiveRecord
|
|
693
693
|
#
|
694
694
|
# If the options provided include an +if_exists+ key, it will be used to check if the
|
695
695
|
# column does not exist. This will silently ignore the migration rather than raising
|
696
|
-
# if the column was already
|
696
|
+
# if the column was already removed.
|
697
697
|
#
|
698
698
|
# remove_column(:suppliers, :qualification, if_exists: true)
|
699
699
|
def remove_column(table_name, column_name, type = nil, **options)
|
@@ -1334,7 +1334,6 @@ module ActiveRecord
|
|
1334
1334
|
execute schema_creation.accept(at)
|
1335
1335
|
end
|
1336
1336
|
|
1337
|
-
|
1338
1337
|
# Checks to see if a check constraint exists on a table for a given check constraint definition.
|
1339
1338
|
#
|
1340
1339
|
# check_constraint_exists?(:products, name: "price_check")
|
@@ -1346,6 +1345,13 @@ module ActiveRecord
|
|
1346
1345
|
check_constraint_for(table_name, **options).present?
|
1347
1346
|
end
|
1348
1347
|
|
1348
|
+
def remove_constraint(table_name, constraint_name) # :nodoc:
|
1349
|
+
at = create_alter_table(table_name)
|
1350
|
+
at.drop_constraint(constraint_name)
|
1351
|
+
|
1352
|
+
execute schema_creation.accept(at)
|
1353
|
+
end
|
1354
|
+
|
1349
1355
|
def dump_schema_information # :nodoc:
|
1350
1356
|
versions = pool.schema_migration.versions
|
1351
1357
|
insert_versions_sql(versions) if versions.any?
|
@@ -98,7 +98,7 @@ module ActiveRecord
|
|
98
98
|
end
|
99
99
|
|
100
100
|
def supports_index_sort_order?
|
101
|
-
|
101
|
+
mariadb? ? database_version >= "10.8.1" : database_version >= "8.0.1"
|
102
102
|
end
|
103
103
|
|
104
104
|
def supports_expression_index?
|
@@ -628,7 +628,7 @@ module ActiveRecord
|
|
628
628
|
end
|
629
629
|
|
630
630
|
def build_insert_sql(insert) # :nodoc:
|
631
|
-
no_op_column = quote_column_name(insert.keys.first)
|
631
|
+
no_op_column = quote_column_name(insert.keys.first) if insert.keys.first
|
632
632
|
|
633
633
|
# MySQL 8.0.19 replaces `VALUES(<expression>)` clauses with row and column alias names, see https://dev.mysql.com/worklog/task/?id=6312 .
|
634
634
|
# then MySQL 8.0.20 deprecates the `VALUES(<expression>)` see https://dev.mysql.com/worklog/task/?id=13325 .
|
@@ -637,7 +637,9 @@ module ActiveRecord
|
|
637
637
|
sql = +"INSERT #{insert.into} #{insert.values_list} AS #{values_alias}"
|
638
638
|
|
639
639
|
if insert.skip_duplicates?
|
640
|
-
|
640
|
+
if no_op_column
|
641
|
+
sql << " ON DUPLICATE KEY UPDATE #{no_op_column}=#{values_alias}.#{no_op_column}"
|
642
|
+
end
|
641
643
|
elsif insert.update_duplicates?
|
642
644
|
if insert.raw_update_sql?
|
643
645
|
sql = +"INSERT #{insert.into} #{insert.values_list} ON DUPLICATE KEY UPDATE #{insert.raw_update_sql}"
|
@@ -651,7 +653,9 @@ module ActiveRecord
|
|
651
653
|
sql = +"INSERT #{insert.into} #{insert.values_list}"
|
652
654
|
|
653
655
|
if insert.skip_duplicates?
|
654
|
-
|
656
|
+
if no_op_column
|
657
|
+
sql << " ON DUPLICATE KEY UPDATE #{no_op_column}=#{no_op_column}"
|
658
|
+
end
|
655
659
|
elsif insert.update_duplicates?
|
656
660
|
sql << " ON DUPLICATE KEY UPDATE "
|
657
661
|
if insert.raw_update_sql?
|
@@ -45,12 +45,10 @@ Rails needs superuser privileges to disable referential integrity.
|
|
45
45
|
BEGIN
|
46
46
|
FOR r IN (
|
47
47
|
SELECT FORMAT(
|
48
|
-
'UPDATE pg_constraint SET convalidated=false WHERE conname = ''%I'' AND connamespace::regnamespace = ''%I''::regnamespace; ALTER TABLE %I.%I VALIDATE CONSTRAINT %I;',
|
48
|
+
'UPDATE pg_catalog.pg_constraint SET convalidated=false WHERE conname = ''%1$I'' AND connamespace::regnamespace = ''%2$I''::regnamespace; ALTER TABLE %2$I.%3$I VALIDATE CONSTRAINT %1$I;',
|
49
49
|
constraint_name,
|
50
50
|
table_schema,
|
51
|
-
|
52
|
-
table_name,
|
53
|
-
constraint_name
|
51
|
+
table_name
|
54
52
|
) AS constraint_check
|
55
53
|
FROM information_schema.table_constraints WHERE constraint_type = 'FOREIGN KEY'
|
56
54
|
)
|
@@ -11,9 +11,7 @@ module ActiveRecord
|
|
11
11
|
sql = super
|
12
12
|
sql << o.constraint_validations.map { |fk| visit_ValidateConstraint fk }.join(" ")
|
13
13
|
sql << o.exclusion_constraint_adds.map { |con| visit_AddExclusionConstraint con }.join(" ")
|
14
|
-
sql << o.exclusion_constraint_drops.map { |con| visit_DropExclusionConstraint con }.join(" ")
|
15
14
|
sql << o.unique_constraint_adds.map { |con| visit_AddUniqueConstraint con }.join(" ")
|
16
|
-
sql << o.unique_constraint_drops.map { |con| visit_DropUniqueConstraint con }.join(" ")
|
17
15
|
end
|
18
16
|
|
19
17
|
def visit_AddForeignKey(o)
|
@@ -72,18 +70,10 @@ module ActiveRecord
|
|
72
70
|
"ADD #{accept(o)}"
|
73
71
|
end
|
74
72
|
|
75
|
-
def visit_DropExclusionConstraint(name)
|
76
|
-
"DROP CONSTRAINT #{quote_column_name(name)}"
|
77
|
-
end
|
78
|
-
|
79
73
|
def visit_AddUniqueConstraint(o)
|
80
74
|
"ADD #{accept(o)}"
|
81
75
|
end
|
82
76
|
|
83
|
-
def visit_DropUniqueConstraint(name)
|
84
|
-
"DROP CONSTRAINT #{quote_column_name(name)}"
|
85
|
-
end
|
86
|
-
|
87
77
|
def visit_ChangeColumnDefinition(o)
|
88
78
|
column = o.column
|
89
79
|
column.sql_type = type_to_sql(column.type, **column.options)
|
@@ -356,15 +356,13 @@ module ActiveRecord
|
|
356
356
|
|
357
357
|
# = Active Record PostgreSQL Adapter Alter \Table
|
358
358
|
class AlterTable < ActiveRecord::ConnectionAdapters::AlterTable
|
359
|
-
attr_reader :constraint_validations, :exclusion_constraint_adds, :
|
359
|
+
attr_reader :constraint_validations, :exclusion_constraint_adds, :unique_constraint_adds
|
360
360
|
|
361
361
|
def initialize(td)
|
362
362
|
super
|
363
363
|
@constraint_validations = []
|
364
364
|
@exclusion_constraint_adds = []
|
365
|
-
@exclusion_constraint_drops = []
|
366
365
|
@unique_constraint_adds = []
|
367
|
-
@unique_constraint_drops = []
|
368
366
|
end
|
369
367
|
|
370
368
|
def validate_constraint(name)
|
@@ -375,17 +373,9 @@ module ActiveRecord
|
|
375
373
|
@exclusion_constraint_adds << @td.new_exclusion_constraint_definition(expression, options)
|
376
374
|
end
|
377
375
|
|
378
|
-
def drop_exclusion_constraint(constraint_name)
|
379
|
-
@exclusion_constraint_drops << constraint_name
|
380
|
-
end
|
381
|
-
|
382
376
|
def add_unique_constraint(column_name, options)
|
383
377
|
@unique_constraint_adds << @td.new_unique_constraint_definition(column_name, options)
|
384
378
|
end
|
385
|
-
|
386
|
-
def drop_unique_constraint(unique_constraint_name)
|
387
|
-
@unique_constraint_drops << unique_constraint_name
|
388
|
-
end
|
389
379
|
end
|
390
380
|
end
|
391
381
|
end
|
@@ -299,6 +299,8 @@ module ActiveRecord
|
|
299
299
|
|
300
300
|
# Returns the sequence name for a table's primary key or some other specified key.
|
301
301
|
def default_sequence_name(table_name, pk = "id") # :nodoc:
|
302
|
+
return nil if pk.is_a?(Array)
|
303
|
+
|
302
304
|
result = serial_sequence(table_name, pk)
|
303
305
|
return nil unless result
|
304
306
|
Utils.extract_schema_qualified_name(result).to_s
|
@@ -764,10 +766,7 @@ module ActiveRecord
|
|
764
766
|
def remove_exclusion_constraint(table_name, expression = nil, **options)
|
765
767
|
excl_name_to_delete = exclusion_constraint_for!(table_name, expression: expression, **options).name
|
766
768
|
|
767
|
-
|
768
|
-
at.drop_exclusion_constraint(excl_name_to_delete)
|
769
|
-
|
770
|
-
execute schema_creation.accept(at)
|
769
|
+
remove_constraint(table_name, excl_name_to_delete)
|
771
770
|
end
|
772
771
|
|
773
772
|
# Adds a new unique constraint to the table.
|
@@ -819,10 +818,7 @@ module ActiveRecord
|
|
819
818
|
def remove_unique_constraint(table_name, column_name = nil, **options)
|
820
819
|
unique_name_to_delete = unique_constraint_for!(table_name, column: column_name, **options).name
|
821
820
|
|
822
|
-
|
823
|
-
at.drop_unique_constraint(unique_name_to_delete)
|
824
|
-
|
825
|
-
execute schema_creation.accept(at)
|
821
|
+
remove_constraint(table_name, unique_name_to_delete)
|
826
822
|
end
|
827
823
|
|
828
824
|
# Maps logical Rails types to PostgreSQL-specific data types.
|
@@ -576,9 +576,9 @@ module ActiveRecord
|
|
576
576
|
|
577
577
|
# Rename an existing enum type to something else.
|
578
578
|
def rename_enum(name, **options)
|
579
|
-
|
579
|
+
new_name = options.fetch(:to) { raise ArgumentError, ":to is required" }
|
580
580
|
|
581
|
-
exec_query("ALTER TYPE #{quote_table_name(name)} RENAME TO #{
|
581
|
+
exec_query("ALTER TYPE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}").tap { reload_type_map }
|
582
582
|
end
|
583
583
|
|
584
584
|
# Add enum value to an existing enum type.
|
@@ -586,14 +586,14 @@ module ActiveRecord
|
|
586
586
|
before, after = options.values_at(:before, :after)
|
587
587
|
sql = +"ALTER TYPE #{quote_table_name(type_name)} ADD VALUE"
|
588
588
|
sql << " IF NOT EXISTS" if options[:if_not_exists]
|
589
|
-
sql << "
|
589
|
+
sql << " #{quote(value)}"
|
590
590
|
|
591
591
|
if before && after
|
592
592
|
raise ArgumentError, "Cannot have both :before and :after at the same time"
|
593
593
|
elsif before
|
594
|
-
sql << " BEFORE
|
594
|
+
sql << " BEFORE #{quote(before)}"
|
595
595
|
elsif after
|
596
|
-
sql << " AFTER
|
596
|
+
sql << " AFTER #{quote(after)}"
|
597
597
|
end
|
598
598
|
|
599
599
|
execute(sql).tap { reload_type_map }
|
@@ -608,7 +608,7 @@ module ActiveRecord
|
|
608
608
|
from = options.fetch(:from) { raise ArgumentError, ":from is required" }
|
609
609
|
to = options.fetch(:to) { raise ArgumentError, ":to is required" }
|
610
610
|
|
611
|
-
execute("ALTER TYPE #{quote_table_name(type_name)} RENAME VALUE
|
611
|
+
execute("ALTER TYPE #{quote_table_name(type_name)} RENAME VALUE #{quote(from)} TO #{quote(to)}").tap {
|
612
612
|
reload_type_map
|
613
613
|
}
|
614
614
|
end
|
@@ -671,8 +671,8 @@ module ActiveRecord
|
|
671
671
|
m.register_type "int4", Type::Integer.new(limit: 4)
|
672
672
|
m.register_type "int8", Type::Integer.new(limit: 8)
|
673
673
|
m.register_type "oid", OID::Oid.new
|
674
|
-
m.register_type "float4", Type::Float.new
|
675
|
-
m.
|
674
|
+
m.register_type "float4", Type::Float.new(limit: 24)
|
675
|
+
m.register_type "float8", Type::Float.new
|
676
676
|
m.register_type "text", Type::Text.new
|
677
677
|
register_class_with_limit m, "varchar", Type::String
|
678
678
|
m.alias_type "char", "varchar"
|
@@ -68,7 +68,7 @@ module ActiveRecord
|
|
68
68
|
raise StandardError, "You need to enable the shared-cache mode in SQLite mode before attempting to change the transaction isolation level" unless shared_cache?
|
69
69
|
end
|
70
70
|
|
71
|
-
internal_execute("BEGIN #{mode} TRANSACTION", allow_retry: true, materialize_transactions: false)
|
71
|
+
internal_execute("BEGIN #{mode} TRANSACTION", "TRANSACTION", allow_retry: true, materialize_transactions: false)
|
72
72
|
if isolation
|
73
73
|
@previous_read_uncommitted = query_value("PRAGMA read_uncommitted")
|
74
74
|
internal_execute("PRAGMA read_uncommitted=ON", "TRANSACTION", allow_retry: true, materialize_transactions: false)
|
@@ -31,62 +31,6 @@ module ActiveRecord
|
|
31
31
|
class_name, path_to_adapter = @adapters[adapter_name.to_s]
|
32
32
|
|
33
33
|
unless class_name
|
34
|
-
# To provide better error messages for adapters expecting the pre-7.2 adapter registration API, we attempt
|
35
|
-
# to load the adapter file from the old location which was required by convention, and then raise an error
|
36
|
-
# describing how to upgrade the adapter to the new API.
|
37
|
-
legacy_adapter_path = "active_record/connection_adapters/#{adapter_name}_adapter"
|
38
|
-
legacy_adapter_connection_method_name = "#{adapter_name}_connection".to_sym
|
39
|
-
|
40
|
-
begin
|
41
|
-
require legacy_adapter_path
|
42
|
-
# If we reach here it means we found the found a file that may be the legacy adapter and should raise.
|
43
|
-
if ActiveRecord::ConnectionHandling.method_defined?(legacy_adapter_connection_method_name)
|
44
|
-
# If we find the connection method then we care certain it is a legacy adapter.
|
45
|
-
deprecation_message = <<~MSG.squish
|
46
|
-
Database configuration specifies '#{adapter_name}' adapter but that adapter has not been registered.
|
47
|
-
Rails 7.2 has changed the way Active Record database adapters are loaded. The adapter needs to be
|
48
|
-
updated to register itself rather than being loaded by convention.
|
49
|
-
Ensure that the adapter in the Gemfile is at the latest version. If it is, then the adapter may need to
|
50
|
-
be modified.
|
51
|
-
See:
|
52
|
-
https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters.html#method-c-register
|
53
|
-
MSG
|
54
|
-
|
55
|
-
exception_message = <<~MSG.squish
|
56
|
-
Database configuration specifies '#{adapter_name}' adapter but that adapter has not been registered.
|
57
|
-
Ensure that the adapter in the Gemfile is at the latest version. If it is, then the adapter may need to
|
58
|
-
be modified.
|
59
|
-
MSG
|
60
|
-
else
|
61
|
-
# If we do not find the connection method we are much less certain it is a legacy adapter. Even though the
|
62
|
-
# file exists in the location defined by convenntion, it does not necessarily mean that file is supposed
|
63
|
-
# to define the adapter the legacy way. So raise an error that explains both possibilities.
|
64
|
-
deprecation_message = <<~MSG.squish
|
65
|
-
Database configuration specifies nonexistent '#{adapter_name}' adapter.
|
66
|
-
Available adapters are: #{@adapters.keys.sort.join(", ")}.
|
67
|
-
Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary
|
68
|
-
adapter gem to your Gemfile if it's not in the list of available adapters.
|
69
|
-
Rails 7.2 has changed the way Active Record database adapters are loaded. Ensure that the adapter in
|
70
|
-
the Gemfile is at the latest version. If it is up to date, the adapter may need to be modified.
|
71
|
-
See:
|
72
|
-
https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters.html#method-c-register
|
73
|
-
MSG
|
74
|
-
|
75
|
-
exception_message = <<~MSG.squish
|
76
|
-
Database configuration specifies nonexistent '#{adapter_name}' adapter.
|
77
|
-
Available adapters are: #{@adapters.keys.sort.join(", ")}.
|
78
|
-
Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary
|
79
|
-
adapter gem to your Gemfile and that it is at its latest version. If it is up to date, the adapter may
|
80
|
-
need to be modified.
|
81
|
-
MSG
|
82
|
-
end
|
83
|
-
|
84
|
-
ActiveRecord.deprecator.warn(deprecation_message)
|
85
|
-
raise AdapterNotFound, exception_message
|
86
|
-
rescue LoadError => error
|
87
|
-
# The adapter was not found in the legacy location so fall through to the error handling for a missing adapter.
|
88
|
-
end
|
89
|
-
|
90
34
|
raise AdapterNotFound, <<~MSG.squish
|
91
35
|
Database configuration specifies nonexistent '#{adapter_name}' adapter.
|
92
36
|
Available adapters are: #{@adapters.keys.sort.join(", ")}.
|