activerecord 6.1.7.10 → 7.0.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +726 -1404
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/active_record/aggregations.rb +1 -1
- data/lib/active_record/association_relation.rb +0 -10
- data/lib/active_record/associations/association.rb +31 -9
- data/lib/active_record/associations/association_scope.rb +1 -3
- data/lib/active_record/associations/belongs_to_association.rb +15 -4
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
- data/lib/active_record/associations/builder/association.rb +8 -2
- data/lib/active_record/associations/builder/belongs_to.rb +19 -6
- data/lib/active_record/associations/builder/collection_association.rb +1 -1
- data/lib/active_record/associations/builder/has_many.rb +3 -2
- data/lib/active_record/associations/builder/has_one.rb +2 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -2
- data/lib/active_record/associations/collection_association.rb +14 -23
- data/lib/active_record/associations/collection_proxy.rb +8 -3
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +2 -1
- data/lib/active_record/associations/has_one_association.rb +10 -7
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/preloader/association.rb +161 -47
- data/lib/active_record/associations/preloader/batch.rb +51 -0
- data/lib/active_record/associations/preloader/branch.rb +147 -0
- data/lib/active_record/associations/preloader/through_association.rb +37 -11
- data/lib/active_record/associations/preloader.rb +46 -110
- data/lib/active_record/associations/singular_association.rb +8 -2
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +76 -81
- data/lib/active_record/asynchronous_queries_tracker.rb +57 -0
- data/lib/active_record/attribute_assignment.rb +1 -1
- data/lib/active_record/attribute_methods/before_type_cast.rb +7 -2
- data/lib/active_record/attribute_methods/dirty.rb +41 -16
- data/lib/active_record/attribute_methods/primary_key.rb +2 -2
- data/lib/active_record/attribute_methods/query.rb +2 -2
- data/lib/active_record/attribute_methods/read.rb +7 -5
- data/lib/active_record/attribute_methods/serialization.rb +66 -12
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
- data/lib/active_record/attribute_methods/write.rb +7 -10
- data/lib/active_record/attribute_methods.rb +6 -9
- data/lib/active_record/attributes.rb +24 -35
- data/lib/active_record/autosave_association.rb +3 -18
- data/lib/active_record/base.rb +19 -1
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/coders/yaml_column.rb +2 -14
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +312 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +31 -558
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +45 -21
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
- data/lib/active_record/connection_adapters/abstract/quoting.rb +12 -14
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +30 -13
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +60 -16
- data/lib/active_record/connection_adapters/abstract/transaction.rb +3 -3
- data/lib/active_record/connection_adapters/abstract_adapter.rb +112 -66
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +96 -81
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +33 -23
- data/lib/active_record/connection_adapters/mysql/quoting.rb +16 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +1 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -6
- data/lib/active_record/connection_adapters/pool_config.rb +1 -3
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +19 -14
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +6 -32
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +32 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +12 -12
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +159 -102
- data/lib/active_record/connection_adapters/schema_cache.rb +36 -37
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +23 -19
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +4 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -30
- data/lib/active_record/connection_adapters.rb +6 -5
- data/lib/active_record/connection_handling.rb +20 -38
- data/lib/active_record/core.rb +111 -125
- data/lib/active_record/database_configurations/connection_url_resolver.rb +0 -1
- data/lib/active_record/database_configurations/database_config.rb +12 -0
- data/lib/active_record/database_configurations/hash_config.rb +27 -1
- data/lib/active_record/database_configurations/url_config.rb +2 -2
- data/lib/active_record/database_configurations.rb +17 -9
- data/lib/active_record/delegated_type.rb +33 -11
- data/lib/active_record/destroy_association_async_job.rb +1 -1
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
- data/lib/active_record/encryption/cipher.rb +53 -0
- data/lib/active_record/encryption/config.rb +44 -0
- data/lib/active_record/encryption/configurable.rb +61 -0
- data/lib/active_record/encryption/context.rb +35 -0
- data/lib/active_record/encryption/contexts.rb +72 -0
- data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
- data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
- data/lib/active_record/encryption/encryptable_record.rb +208 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
- data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
- data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
- data/lib/active_record/encryption/encryptor.rb +155 -0
- data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
- data/lib/active_record/encryption/errors.rb +15 -0
- data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +29 -0
- data/lib/active_record/encryption/key.rb +28 -0
- data/lib/active_record/encryption/key_generator.rb +42 -0
- data/lib/active_record/encryption/key_provider.rb +46 -0
- data/lib/active_record/encryption/message.rb +33 -0
- data/lib/active_record/encryption/message_serializer.rb +80 -0
- data/lib/active_record/encryption/null_encryptor.rb +21 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
- data/lib/active_record/encryption/scheme.rb +99 -0
- data/lib/active_record/encryption.rb +55 -0
- data/lib/active_record/enum.rb +41 -41
- data/lib/active_record/errors.rb +66 -3
- data/lib/active_record/fixture_set/file.rb +15 -1
- data/lib/active_record/fixture_set/table_row.rb +40 -5
- data/lib/active_record/fixture_set/table_rows.rb +4 -4
- data/lib/active_record/fixtures.rb +16 -11
- data/lib/active_record/future_result.rb +139 -0
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +55 -17
- data/lib/active_record/insert_all.rb +34 -5
- data/lib/active_record/integration.rb +1 -1
- data/lib/active_record/internal_metadata.rb +1 -5
- data/lib/active_record/locking/optimistic.rb +10 -9
- data/lib/active_record/log_subscriber.rb +6 -2
- data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
- data/lib/active_record/middleware/database_selector.rb +8 -3
- data/lib/active_record/migration/command_recorder.rb +4 -4
- data/lib/active_record/migration/compatibility.rb +89 -10
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration.rb +109 -79
- data/lib/active_record/model_schema.rb +45 -31
- data/lib/active_record/nested_attributes.rb +3 -3
- data/lib/active_record/no_touching.rb +2 -2
- data/lib/active_record/null_relation.rb +2 -6
- data/lib/active_record/persistence.rb +134 -45
- data/lib/active_record/query_cache.rb +2 -2
- data/lib/active_record/query_logs.rb +203 -0
- data/lib/active_record/querying.rb +15 -5
- data/lib/active_record/railtie.rb +117 -17
- data/lib/active_record/railties/controller_runtime.rb +1 -1
- data/lib/active_record/railties/databases.rake +72 -48
- data/lib/active_record/readonly_attributes.rb +11 -0
- data/lib/active_record/reflection.rb +45 -44
- data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
- data/lib/active_record/relation/batches.rb +3 -3
- data/lib/active_record/relation/calculations.rb +39 -26
- data/lib/active_record/relation/delegation.rb +6 -6
- data/lib/active_record/relation/finder_methods.rb +31 -22
- data/lib/active_record/relation/merger.rb +20 -13
- data/lib/active_record/relation/predicate_builder.rb +1 -6
- data/lib/active_record/relation/query_attribute.rb +5 -11
- data/lib/active_record/relation/query_methods.rb +230 -49
- data/lib/active_record/relation/record_fetch_warning.rb +2 -2
- data/lib/active_record/relation/spawn_methods.rb +2 -2
- data/lib/active_record/relation/where_clause.rb +8 -4
- data/lib/active_record/relation.rb +166 -77
- data/lib/active_record/result.rb +17 -2
- data/lib/active_record/runtime_registry.rb +2 -4
- data/lib/active_record/sanitization.rb +11 -7
- data/lib/active_record/schema_dumper.rb +3 -3
- data/lib/active_record/schema_migration.rb +0 -4
- data/lib/active_record/scoping/default.rb +61 -12
- data/lib/active_record/scoping/named.rb +3 -11
- data/lib/active_record/scoping.rb +40 -22
- data/lib/active_record/serialization.rb +1 -1
- data/lib/active_record/signed_id.rb +1 -1
- data/lib/active_record/store.rb +1 -6
- data/lib/active_record/tasks/database_tasks.rb +106 -22
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/postgresql_database_tasks.rb +14 -11
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +9 -13
- data/lib/active_record/timestamp.rb +3 -4
- data/lib/active_record/transactions.rb +9 -14
- data/lib/active_record/translation.rb +2 -2
- data/lib/active_record/type/adapter_specific_registry.rb +32 -7
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
- data/lib/active_record/type/internal/timezone.rb +2 -2
- data/lib/active_record/type/serialized.rb +1 -1
- data/lib/active_record/type/type_map.rb +17 -20
- data/lib/active_record/type.rb +1 -2
- data/lib/active_record/validations/associated.rb +1 -1
- data/lib/active_record.rb +170 -2
- data/lib/arel/attributes/attribute.rb +0 -8
- data/lib/arel/crud.rb +18 -22
- data/lib/arel/delete_manager.rb +2 -4
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/casted.rb +1 -1
- data/lib/arel/nodes/delete_statement.rb +8 -13
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/select_core.rb +2 -2
- data/lib/arel/nodes/select_statement.rb +2 -2
- data/lib/arel/nodes/update_statement.rb +3 -2
- data/lib/arel/predications.rb +1 -1
- data/lib/arel/select_manager.rb +10 -4
- data/lib/arel/table.rb +0 -1
- data/lib/arel/tree_manager.rb +0 -12
- data/lib/arel/update_manager.rb +2 -4
- data/lib/arel/visitors/dot.rb +80 -90
- data/lib/arel/visitors/mysql.rb +6 -1
- data/lib/arel/visitors/postgresql.rb +0 -10
- data/lib/arel/visitors/to_sql.rb +43 -2
- data/lib/arel.rb +1 -1
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
- metadata +52 -14
@@ -5,7 +5,7 @@ require "active_support/core_ext/enumerable"
|
|
5
5
|
module ActiveRecord
|
6
6
|
class InsertAll # :nodoc:
|
7
7
|
attr_reader :model, :connection, :inserts, :keys
|
8
|
-
attr_reader :on_duplicate, :returning, :unique_by
|
8
|
+
attr_reader :on_duplicate, :returning, :unique_by, :update_sql
|
9
9
|
|
10
10
|
def initialize(model, inserts, on_duplicate:, returning: nil, unique_by: nil)
|
11
11
|
raise ArgumentError, "Empty list of attributes passed" if inserts.blank?
|
@@ -13,6 +13,14 @@ module ActiveRecord
|
|
13
13
|
@model, @connection, @inserts, @keys = model, model.connection, inserts, inserts.first.keys.map(&:to_s)
|
14
14
|
@on_duplicate, @returning, @unique_by = on_duplicate, returning, unique_by
|
15
15
|
|
16
|
+
disallow_raw_sql!(returning)
|
17
|
+
disallow_raw_sql!(on_duplicate)
|
18
|
+
|
19
|
+
if Arel.arel_node?(on_duplicate)
|
20
|
+
@update_sql = on_duplicate
|
21
|
+
@on_duplicate = :update
|
22
|
+
end
|
23
|
+
|
16
24
|
if model.scope_attributes?
|
17
25
|
@scope_attributes = model.scope_attributes
|
18
26
|
@keys |= @scope_attributes.keys
|
@@ -131,6 +139,15 @@ module ActiveRecord
|
|
131
139
|
end
|
132
140
|
end
|
133
141
|
|
142
|
+
def disallow_raw_sql!(value)
|
143
|
+
return if !value.is_a?(String) || Arel.arel_node?(value)
|
144
|
+
|
145
|
+
raise ArgumentError, "Dangerous query method (method whose arguments are used as raw " \
|
146
|
+
"SQL) called: #{value}. " \
|
147
|
+
"Known-safe values can be passed " \
|
148
|
+
"by wrapping them in Arel.sql()."
|
149
|
+
end
|
150
|
+
|
134
151
|
class Builder # :nodoc:
|
135
152
|
attr_reader :model
|
136
153
|
|
@@ -155,7 +172,13 @@ module ActiveRecord
|
|
155
172
|
end
|
156
173
|
|
157
174
|
def returning
|
158
|
-
|
175
|
+
return unless insert_all.returning
|
176
|
+
|
177
|
+
if insert_all.returning.is_a?(String)
|
178
|
+
insert_all.returning
|
179
|
+
else
|
180
|
+
format_columns(insert_all.returning)
|
181
|
+
end
|
159
182
|
end
|
160
183
|
|
161
184
|
def conflict_target
|
@@ -173,13 +196,19 @@ module ActiveRecord
|
|
173
196
|
end
|
174
197
|
|
175
198
|
def touch_model_timestamps_unless(&block)
|
176
|
-
model.
|
199
|
+
model.timestamp_attributes_for_update_in_model.filter_map do |column_name|
|
177
200
|
if touch_timestamp_attribute?(column_name)
|
178
|
-
"#{column_name}=(CASE WHEN (#{updatable_columns.map(&block).join(" AND ")}) THEN #{model.quoted_table_name}.#{column_name} ELSE
|
201
|
+
"#{column_name}=(CASE WHEN (#{updatable_columns.map(&block).join(" AND ")}) THEN #{model.quoted_table_name}.#{column_name} ELSE #{connection.high_precision_current_timestamp} END),"
|
179
202
|
end
|
180
|
-
end.
|
203
|
+
end.join
|
181
204
|
end
|
182
205
|
|
206
|
+
def raw_update_sql
|
207
|
+
insert_all.update_sql
|
208
|
+
end
|
209
|
+
|
210
|
+
alias raw_update_sql? raw_update_sql
|
211
|
+
|
183
212
|
private
|
184
213
|
attr_reader :connection, :insert_all
|
185
214
|
|
@@ -177,7 +177,7 @@ module ActiveRecord
|
|
177
177
|
def can_use_fast_cache_version?(timestamp)
|
178
178
|
timestamp.is_a?(String) &&
|
179
179
|
cache_timestamp_format == :usec &&
|
180
|
-
default_timezone == :utc &&
|
180
|
+
ActiveRecord.default_timezone == :utc &&
|
181
181
|
!updated_at_came_from_user?
|
182
182
|
end
|
183
183
|
|
@@ -17,10 +17,6 @@ module ActiveRecord
|
|
17
17
|
ActiveRecord::Base.connection.use_metadata_table?
|
18
18
|
end
|
19
19
|
|
20
|
-
def _internal?
|
21
|
-
true
|
22
|
-
end
|
23
|
-
|
24
20
|
def primary_key
|
25
21
|
"key"
|
26
22
|
end
|
@@ -38,7 +34,7 @@ module ActiveRecord
|
|
38
34
|
def [](key)
|
39
35
|
return unless enabled?
|
40
36
|
|
41
|
-
where(key: key).
|
37
|
+
where(key: key).pick(:value)
|
42
38
|
end
|
43
39
|
|
44
40
|
# Creates an internal metadata table with columns +key+ and +value+
|
@@ -56,11 +56,11 @@ module ActiveRecord
|
|
56
56
|
class_attribute :lock_optimistically, instance_writer: false, default: true
|
57
57
|
end
|
58
58
|
|
59
|
-
def locking_enabled?
|
59
|
+
def locking_enabled? # :nodoc:
|
60
60
|
self.class.locking_enabled?
|
61
61
|
end
|
62
62
|
|
63
|
-
def increment!(*, **)
|
63
|
+
def increment!(*, **) # :nodoc:
|
64
64
|
super.tap do
|
65
65
|
if locking_enabled?
|
66
66
|
self[self.class.locking_column] += 1
|
@@ -90,7 +90,9 @@ module ActiveRecord
|
|
90
90
|
begin
|
91
91
|
locking_column = self.class.locking_column
|
92
92
|
lock_attribute_was = @attributes[locking_column]
|
93
|
-
|
93
|
+
|
94
|
+
update_constraints = _primary_key_constraints_hash
|
95
|
+
update_constraints[locking_column] = _lock_value_for_database(locking_column)
|
94
96
|
|
95
97
|
attribute_names = attribute_names.dup if attribute_names.frozen?
|
96
98
|
attribute_names << locking_column
|
@@ -99,8 +101,7 @@ module ActiveRecord
|
|
99
101
|
|
100
102
|
affected_rows = self.class._update_record(
|
101
103
|
attributes_with_values(attribute_names),
|
102
|
-
|
103
|
-
locking_column => lock_value_for_database
|
104
|
+
update_constraints
|
104
105
|
)
|
105
106
|
|
106
107
|
if affected_rows != 1
|
@@ -121,10 +122,10 @@ module ActiveRecord
|
|
121
122
|
|
122
123
|
locking_column = self.class.locking_column
|
123
124
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
)
|
125
|
+
delete_constraints = _primary_key_constraints_hash
|
126
|
+
delete_constraints[locking_column] = _lock_value_for_database(locking_column)
|
127
|
+
|
128
|
+
affected_rows = self.class._delete_record(delete_constraints)
|
128
129
|
|
129
130
|
if affected_rows != 1
|
130
131
|
raise ActiveRecord::StaleObjectError.new(self, "destroy")
|
@@ -37,7 +37,11 @@ module ActiveRecord
|
|
37
37
|
|
38
38
|
return if IGNORE_PAYLOAD_NAMES.include?(payload[:name])
|
39
39
|
|
40
|
-
name
|
40
|
+
name = if payload[:async]
|
41
|
+
"ASYNC #{payload[:name]} (#{payload[:lock_wait].round(1)}ms) (db time #{event.duration.round(1)}ms)"
|
42
|
+
else
|
43
|
+
"#{payload[:name]} (#{event.duration.round(1)}ms)"
|
44
|
+
end
|
41
45
|
name = "CACHE #{name}" if payload[:cached]
|
42
46
|
sql = payload[:sql]
|
43
47
|
binds = nil
|
@@ -115,7 +119,7 @@ module ActiveRecord
|
|
115
119
|
def debug(progname = nil, &block)
|
116
120
|
return unless super
|
117
121
|
|
118
|
-
if ActiveRecord
|
122
|
+
if ActiveRecord.verbose_query_logs
|
119
123
|
log_query_source
|
120
124
|
end
|
121
125
|
end
|
@@ -50,23 +50,19 @@ module ActiveRecord
|
|
50
50
|
|
51
51
|
private
|
52
52
|
def read_from_primary(&blk)
|
53
|
-
ActiveRecord::Base.connected_to(role: ActiveRecord
|
54
|
-
instrumenter.instrument("database_selector.active_record.read_from_primary")
|
55
|
-
yield
|
56
|
-
end
|
53
|
+
ActiveRecord::Base.connected_to(role: ActiveRecord.writing_role, prevent_writes: true) do
|
54
|
+
instrumenter.instrument("database_selector.active_record.read_from_primary", &blk)
|
57
55
|
end
|
58
56
|
end
|
59
57
|
|
60
58
|
def read_from_replica(&blk)
|
61
|
-
ActiveRecord::Base.connected_to(role: ActiveRecord
|
62
|
-
instrumenter.instrument("database_selector.active_record.read_from_replica")
|
63
|
-
yield
|
64
|
-
end
|
59
|
+
ActiveRecord::Base.connected_to(role: ActiveRecord.reading_role, prevent_writes: true) do
|
60
|
+
instrumenter.instrument("database_selector.active_record.read_from_replica", &blk)
|
65
61
|
end
|
66
62
|
end
|
67
63
|
|
68
|
-
def write_to_primary
|
69
|
-
ActiveRecord::Base.connected_to(role: ActiveRecord
|
64
|
+
def write_to_primary
|
65
|
+
ActiveRecord::Base.connected_to(role: ActiveRecord.writing_role, prevent_writes: false) do
|
70
66
|
instrumenter.instrument("database_selector.active_record.wrote_to_primary") do
|
71
67
|
yield
|
72
68
|
ensure
|
@@ -22,9 +22,14 @@ module ActiveRecord
|
|
22
22
|
# To use the DatabaseSelector in your application with default settings add
|
23
23
|
# the following options to your environment config:
|
24
24
|
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
25
|
+
# # This require is only necessary when using `rails new app --minimal`
|
26
|
+
# require "active_support/core_ext/integer/time"
|
27
|
+
#
|
28
|
+
# class Application < Rails::Application
|
29
|
+
# config.active_record.database_selector = { delay: 2.seconds }
|
30
|
+
# config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
|
31
|
+
# config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
|
32
|
+
# end
|
28
33
|
#
|
29
34
|
# New applications will include these lines commented out in the production.rb.
|
30
35
|
#
|
@@ -112,7 +112,7 @@ module ActiveRecord
|
|
112
112
|
record(:"#{method}", args, &block) # record(:create_table, args, &block)
|
113
113
|
end # end
|
114
114
|
EOV
|
115
|
-
ruby2_keywords(method)
|
115
|
+
ruby2_keywords(method)
|
116
116
|
end
|
117
117
|
alias :add_belongs_to :add_reference
|
118
118
|
alias :remove_belongs_to :remove_reference
|
@@ -154,9 +154,9 @@ module ActiveRecord
|
|
154
154
|
|
155
155
|
include StraightReversions
|
156
156
|
|
157
|
-
def invert_transaction(args)
|
157
|
+
def invert_transaction(args, &block)
|
158
158
|
sub_recorder = CommandRecorder.new(delegate)
|
159
|
-
sub_recorder.revert
|
159
|
+
sub_recorder.revert(&block)
|
160
160
|
|
161
161
|
invertions_proc = proc {
|
162
162
|
sub_recorder.replay(self)
|
@@ -286,7 +286,7 @@ module ActiveRecord
|
|
286
286
|
super
|
287
287
|
end
|
288
288
|
end
|
289
|
-
ruby2_keywords(:method_missing)
|
289
|
+
ruby2_keywords(:method_missing)
|
290
290
|
end
|
291
291
|
end
|
292
292
|
end
|
@@ -13,7 +13,77 @@ module ActiveRecord
|
|
13
13
|
const_get(name)
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
# This file exists to ensure that old migrations run the same way they did before a Rails upgrade.
|
17
|
+
# e.g. if you write a migration on Rails 6.1, then upgrade to Rails 7, the migration should do the same thing to your
|
18
|
+
# database as it did when you were running Rails 6.1
|
19
|
+
#
|
20
|
+
# "Current" is an alias for `ActiveRecord::Migration`, it represents the current Rails version.
|
21
|
+
# New migration functionality that will never be backward compatible should be added directly to `ActiveRecord::Migration`.
|
22
|
+
#
|
23
|
+
# There are classes for each prior Rails version. Each class descends from the *next* Rails version, so:
|
24
|
+
# 6.1 < 7.0
|
25
|
+
# 5.2 < 6.0 < 6.1 < 7.0
|
26
|
+
#
|
27
|
+
# If you are introducing new migration functionality that should only apply from Rails 7 onward, then you should
|
28
|
+
# find the class that immediately precedes it (6.1), and override the relevant migration methods to undo your changes.
|
29
|
+
#
|
30
|
+
# For example, Rails 6 added a default value for the `precision` option on datetime columns. So in this file, the `V5_2`
|
31
|
+
# class sets the value of `precision` to `nil` if it's not explicitly provided. This way, the default value will not apply
|
32
|
+
# for migrations written for 5.2, but will for migrations written for 6.0.
|
33
|
+
V7_0 = Current
|
34
|
+
|
35
|
+
class V6_1 < V7_0
|
36
|
+
class PostgreSQLCompat
|
37
|
+
def self.compatible_timestamp_type(type, connection)
|
38
|
+
if connection.adapter_name == "PostgreSQL"
|
39
|
+
# For Rails <= 6.1, :datetime was aliased to :timestamp
|
40
|
+
# See: https://github.com/rails/rails/blob/v6.1.3.2/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L108
|
41
|
+
# From Rails 7 onwards, you can define what :datetime resolves to (the default is still :timestamp)
|
42
|
+
# See `ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type`
|
43
|
+
type.to_sym == :datetime ? :timestamp : type
|
44
|
+
else
|
45
|
+
type
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def add_column(table_name, column_name, type, **options)
|
51
|
+
if type == :datetime
|
52
|
+
options[:precision] ||= nil
|
53
|
+
end
|
54
|
+
|
55
|
+
type = PostgreSQLCompat.compatible_timestamp_type(type, connection)
|
56
|
+
super
|
57
|
+
end
|
58
|
+
|
59
|
+
def create_table(table_name, **options)
|
60
|
+
if block_given?
|
61
|
+
super { |t| yield compatible_table_definition(t) }
|
62
|
+
else
|
63
|
+
super
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
module TableDefinition
|
68
|
+
def new_column_definition(name, type, **options)
|
69
|
+
type = PostgreSQLCompat.compatible_timestamp_type(type, @conn)
|
70
|
+
super
|
71
|
+
end
|
72
|
+
|
73
|
+
def column(name, type, index: nil, **options)
|
74
|
+
options[:precision] ||= nil
|
75
|
+
super
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
def compatible_table_definition(t)
|
81
|
+
class << t
|
82
|
+
prepend TableDefinition
|
83
|
+
end
|
84
|
+
t
|
85
|
+
end
|
86
|
+
end
|
17
87
|
|
18
88
|
class V6_0 < V6_1
|
19
89
|
class ReferenceDefinition < ConnectionAdapters::ReferenceDefinition
|
@@ -24,10 +94,16 @@ module ActiveRecord
|
|
24
94
|
|
25
95
|
module TableDefinition
|
26
96
|
def references(*args, **options)
|
27
|
-
|
28
|
-
|
97
|
+
args.each do |ref_name|
|
98
|
+
ReferenceDefinition.new(ref_name, **options).add_to(self)
|
99
|
+
end
|
29
100
|
end
|
30
101
|
alias :belongs_to :references
|
102
|
+
|
103
|
+
def column(name, type, index: nil, **options)
|
104
|
+
options[:precision] ||= nil
|
105
|
+
super
|
106
|
+
end
|
31
107
|
end
|
32
108
|
|
33
109
|
def create_table(table_name, **options)
|
@@ -55,12 +131,8 @@ module ActiveRecord
|
|
55
131
|
end
|
56
132
|
|
57
133
|
def add_reference(table_name, ref_name, **options)
|
58
|
-
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
options[:_uses_legacy_reference_index_name] = true
|
63
|
-
super
|
134
|
+
ReferenceDefinition.new(ref_name, **options)
|
135
|
+
.add_to(connection.update_table_definition(table_name, self))
|
64
136
|
end
|
65
137
|
alias :add_belongs_to :add_reference
|
66
138
|
|
@@ -79,6 +151,11 @@ module ActiveRecord
|
|
79
151
|
options[:precision] ||= nil
|
80
152
|
super
|
81
153
|
end
|
154
|
+
|
155
|
+
def column(name, type, index: nil, **options)
|
156
|
+
options[:precision] ||= nil
|
157
|
+
super
|
158
|
+
end
|
82
159
|
end
|
83
160
|
|
84
161
|
module CommandRecorder
|
@@ -129,7 +206,7 @@ module ActiveRecord
|
|
129
206
|
class << t
|
130
207
|
prepend TableDefinition
|
131
208
|
end
|
132
|
-
|
209
|
+
t
|
133
210
|
end
|
134
211
|
|
135
212
|
def command_recorder
|
@@ -207,6 +284,8 @@ module ActiveRecord
|
|
207
284
|
if type == :primary_key
|
208
285
|
type = :integer
|
209
286
|
options[:primary_key] = true
|
287
|
+
elsif type == :datetime
|
288
|
+
options[:precision] ||= nil
|
210
289
|
end
|
211
290
|
super
|
212
291
|
end
|