activerecord 7.2.3 → 8.0.4
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 +391 -958
- data/README.rdoc +1 -1
- data/lib/active_record/association_relation.rb +1 -0
- data/lib/active_record/associations/association.rb +34 -10
- data/lib/active_record/associations/builder/association.rb +7 -6
- data/lib/active_record/associations/collection_association.rb +1 -1
- data/lib/active_record/associations/disable_joins_association_scope.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +3 -2
- data/lib/active_record/associations/preloader/association.rb +2 -2
- data/lib/active_record/associations/singular_association.rb +8 -3
- data/lib/active_record/associations.rb +34 -4
- data/lib/active_record/asynchronous_queries_tracker.rb +28 -24
- data/lib/active_record/attribute_methods/primary_key.rb +4 -8
- data/lib/active_record/attribute_methods/query.rb +34 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +2 -12
- data/lib/active_record/autosave_association.rb +69 -27
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +34 -25
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +6 -15
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +90 -43
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +8 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +7 -2
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +34 -7
- data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -5
- data/lib/active_record/connection_adapters/abstract_adapter.rb +31 -43
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +21 -40
- data/lib/active_record/connection_adapters/mysql/quoting.rb +0 -8
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +2 -8
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +50 -45
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +84 -94
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -8
- data/lib/active_record/connection_adapters/pool_config.rb +7 -7
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +72 -43
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +10 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -4
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +1 -11
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +6 -12
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +2 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +59 -16
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +46 -96
- data/lib/active_record/connection_adapters/schema_cache.rb +1 -3
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +80 -100
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +0 -6
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +13 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +9 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +53 -12
- data/lib/active_record/connection_adapters/statement_pool.rb +4 -2
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +37 -67
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +0 -17
- data/lib/active_record/connection_adapters.rb +0 -56
- data/lib/active_record/connection_handling.rb +23 -1
- data/lib/active_record/core.rb +29 -14
- data/lib/active_record/database_configurations/database_config.rb +4 -0
- data/lib/active_record/database_configurations/hash_config.rb +16 -2
- data/lib/active_record/encryption/config.rb +3 -1
- data/lib/active_record/encryption/encryptable_record.rb +4 -4
- data/lib/active_record/encryption/encrypted_attribute_type.rb +10 -1
- data/lib/active_record/encryption/encryptor.rb +16 -8
- data/lib/active_record/encryption/extended_deterministic_queries.rb +4 -2
- data/lib/active_record/encryption/scheme.rb +8 -1
- data/lib/active_record/enum.rb +9 -22
- data/lib/active_record/errors.rb +13 -5
- data/lib/active_record/fixtures.rb +0 -2
- data/lib/active_record/future_result.rb +13 -9
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/insert_all.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/migration/command_recorder.rb +31 -11
- data/lib/active_record/migration/compatibility.rb +5 -2
- data/lib/active_record/migration.rb +38 -42
- data/lib/active_record/model_schema.rb +3 -4
- data/lib/active_record/nested_attributes.rb +4 -6
- data/lib/active_record/persistence.rb +128 -130
- data/lib/active_record/query_logs.rb +102 -50
- data/lib/active_record/query_logs_formatter.rb +17 -28
- data/lib/active_record/querying.rb +8 -8
- data/lib/active_record/railtie.rb +2 -26
- data/lib/active_record/railties/databases.rake +11 -35
- data/lib/active_record/reflection.rb +18 -21
- data/lib/active_record/relation/batches/batch_enumerator.rb +4 -3
- data/lib/active_record/relation/batches.rb +132 -72
- data/lib/active_record/relation/calculations.rb +40 -39
- data/lib/active_record/relation/delegation.rb +25 -14
- data/lib/active_record/relation/finder_methods.rb +18 -18
- data/lib/active_record/relation/merger.rb +8 -8
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -1
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +4 -3
- data/lib/active_record/relation/predicate_builder.rb +13 -0
- data/lib/active_record/relation/query_methods.rb +105 -61
- data/lib/active_record/relation/spawn_methods.rb +7 -7
- data/lib/active_record/relation.rb +79 -61
- data/lib/active_record/result.rb +66 -4
- data/lib/active_record/sanitization.rb +7 -6
- data/lib/active_record/schema_dumper.rb +5 -0
- data/lib/active_record/schema_migration.rb +2 -1
- data/lib/active_record/scoping/named.rb +5 -2
- data/lib/active_record/statement_cache.rb +14 -14
- data/lib/active_record/store.rb +7 -3
- data/lib/active_record/table_metadata.rb +1 -3
- data/lib/active_record/tasks/database_tasks.rb +69 -60
- data/lib/active_record/tasks/mysql_database_tasks.rb +0 -2
- data/lib/active_record/tasks/postgresql_database_tasks.rb +2 -1
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -2
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +12 -0
- data/lib/active_record/token_for.rb +1 -1
- data/lib/active_record/transactions.rb +5 -6
- data/lib/active_record/validations/uniqueness.rb +8 -8
- data/lib/active_record.rb +21 -48
- data/lib/arel/collectors/bind.rb +2 -2
- data/lib/arel/collectors/sql_string.rb +1 -1
- data/lib/arel/collectors/substitute_binds.rb +2 -2
- data/lib/arel/nodes/binary.rb +1 -1
- data/lib/arel/nodes/node.rb +1 -1
- data/lib/arel/nodes/sql_literal.rb +1 -1
- data/lib/arel/table.rb +3 -7
- metadata +9 -10
- data/lib/active_record/relation/record_fetch_warning.rb +0 -52
|
@@ -76,14 +76,70 @@ module ActiveRecord
|
|
|
76
76
|
#
|
|
77
77
|
# config.active_record.cache_query_log_tags = true
|
|
78
78
|
module QueryLogs
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
class GetKeyHandler # :nodoc:
|
|
80
|
+
def initialize(name)
|
|
81
|
+
@name = name
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def call(context)
|
|
85
|
+
context[@name]
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
class IdentityHandler # :nodoc:
|
|
90
|
+
def initialize(value)
|
|
91
|
+
@value = value
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def call(_context)
|
|
95
|
+
@value
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
class ZeroArityHandler # :nodoc:
|
|
100
|
+
def initialize(proc)
|
|
101
|
+
@proc = proc
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def call(_context)
|
|
105
|
+
@proc.call
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
@taggings = {}.freeze
|
|
110
|
+
@tags = [ :application ].freeze
|
|
111
|
+
@prepend_comment = false
|
|
112
|
+
@cache_query_log_tags = false
|
|
113
|
+
@tags_formatter = false
|
|
114
|
+
|
|
84
115
|
thread_mattr_accessor :cached_comment, instance_accessor: false
|
|
85
116
|
|
|
86
117
|
class << self
|
|
118
|
+
attr_reader :tags, :taggings, :tags_formatter # :nodoc:
|
|
119
|
+
attr_accessor :prepend_comment, :cache_query_log_tags # :nodoc:
|
|
120
|
+
|
|
121
|
+
def taggings=(taggings) # :nodoc:
|
|
122
|
+
@taggings = taggings.freeze
|
|
123
|
+
@handlers = rebuild_handlers
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def tags=(tags) # :nodoc:
|
|
127
|
+
@tags = tags.freeze
|
|
128
|
+
@handlers = rebuild_handlers
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def tags_formatter=(format) # :nodoc:
|
|
132
|
+
@formatter = case format
|
|
133
|
+
when :legacy
|
|
134
|
+
LegacyFormatter
|
|
135
|
+
when :sqlcommenter
|
|
136
|
+
SQLCommenter
|
|
137
|
+
else
|
|
138
|
+
raise ArgumentError, "Formatter is unsupported: #{format}"
|
|
139
|
+
end
|
|
140
|
+
@tags_formatter = format
|
|
141
|
+
end
|
|
142
|
+
|
|
87
143
|
def call(sql, connection) # :nodoc:
|
|
88
144
|
comment = self.comment(connection)
|
|
89
145
|
|
|
@@ -100,36 +156,46 @@ module ActiveRecord
|
|
|
100
156
|
self.cached_comment = nil
|
|
101
157
|
end
|
|
102
158
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
when :legacy
|
|
108
|
-
LegacyFormatter.new
|
|
109
|
-
when :sqlcommenter
|
|
110
|
-
SQLCommenter.new
|
|
111
|
-
else
|
|
112
|
-
raise ArgumentError, "Formatter is unsupported: #{formatter}"
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
if Thread.respond_to?(:each_caller_location)
|
|
117
|
-
def query_source_location # :nodoc:
|
|
118
|
-
Thread.each_caller_location do |location|
|
|
119
|
-
frame = LogSubscriber.backtrace_cleaner.clean_frame(location)
|
|
120
|
-
return frame if frame
|
|
121
|
-
end
|
|
122
|
-
nil
|
|
123
|
-
end
|
|
124
|
-
else
|
|
125
|
-
def query_source_location # :nodoc:
|
|
126
|
-
LogSubscriber.backtrace_cleaner.clean(caller_locations(1).each).first
|
|
159
|
+
def query_source_location # :nodoc:
|
|
160
|
+
Thread.each_caller_location do |location|
|
|
161
|
+
frame = LogSubscriber.backtrace_cleaner.clean_frame(location)
|
|
162
|
+
return frame if frame
|
|
127
163
|
end
|
|
164
|
+
nil
|
|
128
165
|
end
|
|
129
166
|
|
|
130
167
|
ActiveSupport::ExecutionContext.after_change { ActiveRecord::QueryLogs.clear_cache }
|
|
131
168
|
|
|
132
169
|
private
|
|
170
|
+
def rebuild_handlers
|
|
171
|
+
handlers = []
|
|
172
|
+
@tags.each do |i|
|
|
173
|
+
if i.is_a?(Hash)
|
|
174
|
+
i.each do |k, v|
|
|
175
|
+
handlers << [k, build_handler(k, v)]
|
|
176
|
+
end
|
|
177
|
+
else
|
|
178
|
+
handlers << [i, build_handler(i)]
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
handlers.sort_by! { |(key, _)| key.to_s }
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def build_handler(name, handler = nil)
|
|
185
|
+
handler ||= @taggings[name]
|
|
186
|
+
if handler.nil?
|
|
187
|
+
GetKeyHandler.new(name)
|
|
188
|
+
elsif handler.respond_to?(:call)
|
|
189
|
+
if handler.arity == 0
|
|
190
|
+
ZeroArityHandler.new(handler)
|
|
191
|
+
else
|
|
192
|
+
handler
|
|
193
|
+
end
|
|
194
|
+
else
|
|
195
|
+
IdentityHandler.new(handler)
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
133
199
|
# Returns an SQL comment +String+ containing the query log tags.
|
|
134
200
|
# Sets and returns a cached comment if <tt>cache_query_log_tags</tt> is +true+.
|
|
135
201
|
def comment(connection)
|
|
@@ -140,10 +206,6 @@ module ActiveRecord
|
|
|
140
206
|
end
|
|
141
207
|
end
|
|
142
208
|
|
|
143
|
-
def formatter
|
|
144
|
-
self.tags_formatter || self.update_formatter(:legacy)
|
|
145
|
-
end
|
|
146
|
-
|
|
147
209
|
def uncached_comment(connection)
|
|
148
210
|
content = tag_content(connection)
|
|
149
211
|
|
|
@@ -169,25 +231,15 @@ module ActiveRecord
|
|
|
169
231
|
context = ActiveSupport::ExecutionContext.to_h
|
|
170
232
|
context[:connection] ||= connection
|
|
171
233
|
|
|
172
|
-
pairs =
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
val = if handler.nil?
|
|
177
|
-
context[key]
|
|
178
|
-
elsif handler.respond_to?(:call)
|
|
179
|
-
if handler.arity == 0
|
|
180
|
-
handler.call
|
|
181
|
-
else
|
|
182
|
-
handler.call(context)
|
|
183
|
-
end
|
|
184
|
-
else
|
|
185
|
-
handler
|
|
186
|
-
end
|
|
187
|
-
[key, val] unless val.nil?
|
|
234
|
+
pairs = @handlers.filter_map do |(key, handler)|
|
|
235
|
+
val = handler.call(context)
|
|
236
|
+
@formatter.format(key, val) unless val.nil?
|
|
188
237
|
end
|
|
189
|
-
|
|
238
|
+
@formatter.join(pairs)
|
|
190
239
|
end
|
|
191
240
|
end
|
|
241
|
+
|
|
242
|
+
@handlers = rebuild_handlers
|
|
243
|
+
self.tags_formatter = :legacy
|
|
192
244
|
end
|
|
193
245
|
end
|
|
@@ -2,40 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
module ActiveRecord
|
|
4
4
|
module QueryLogs
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# Formats the key value pairs into a string.
|
|
11
|
-
def format(pairs)
|
|
12
|
-
pairs.map! do |key, value|
|
|
13
|
-
"#{key}#{key_value_separator}#{format_value(value)}"
|
|
14
|
-
end.join(",")
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
private
|
|
18
|
-
attr_reader :key_value_separator
|
|
19
|
-
|
|
20
|
-
def format_value(value)
|
|
21
|
-
value
|
|
5
|
+
module LegacyFormatter # :nodoc:
|
|
6
|
+
class << self
|
|
7
|
+
# Formats the key value pairs into a string.
|
|
8
|
+
def format(key, value)
|
|
9
|
+
"#{key}:#{value}"
|
|
22
10
|
end
|
|
23
|
-
end
|
|
24
11
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
12
|
+
def join(pairs)
|
|
13
|
+
pairs.join(",")
|
|
14
|
+
end
|
|
28
15
|
end
|
|
16
|
+
end
|
|
29
17
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
18
|
+
class SQLCommenter # :nodoc:
|
|
19
|
+
class << self
|
|
20
|
+
def format(key, value)
|
|
21
|
+
"#{key}='#{ERB::Util.url_encode(value)}'"
|
|
22
|
+
end
|
|
34
23
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"'#{ERB::Util.url_encode(value)}'"
|
|
24
|
+
def join(pairs)
|
|
25
|
+
pairs.join(",")
|
|
38
26
|
end
|
|
27
|
+
end
|
|
39
28
|
end
|
|
40
29
|
end
|
|
41
30
|
end
|
|
@@ -56,12 +56,10 @@ module ActiveRecord
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
# Same as #find_by_sql but perform the query asynchronously and returns an ActiveRecord::Promise.
|
|
59
|
-
def async_find_by_sql(sql, binds = [], preparable: nil, &block)
|
|
60
|
-
|
|
61
|
-
_query_by_sql(c, sql, binds, preparable: preparable, async: true)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
result.then do |result|
|
|
59
|
+
def async_find_by_sql(sql, binds = [], preparable: nil, allow_retry: false, &block)
|
|
60
|
+
with_connection do |c|
|
|
61
|
+
_query_by_sql(c, sql, binds, preparable: preparable, allow_retry: allow_retry, async: true)
|
|
62
|
+
end.then do |result|
|
|
65
63
|
_load_from_sql(result, &block)
|
|
66
64
|
end
|
|
67
65
|
end
|
|
@@ -71,6 +69,8 @@ module ActiveRecord
|
|
|
71
69
|
end
|
|
72
70
|
|
|
73
71
|
def _load_from_sql(result_set, &block) # :nodoc:
|
|
72
|
+
return [] if result_set.empty?
|
|
73
|
+
|
|
74
74
|
column_types = result_set.column_types
|
|
75
75
|
|
|
76
76
|
unless column_types.empty?
|
|
@@ -86,10 +86,10 @@ module ActiveRecord
|
|
|
86
86
|
|
|
87
87
|
message_bus.instrument("instantiation.active_record", payload) do
|
|
88
88
|
if result_set.includes_column?(inheritance_column)
|
|
89
|
-
result_set.map { |record| instantiate(record, column_types, &block) }
|
|
89
|
+
result_set.indexed_rows.map { |record| instantiate(record, column_types, &block) }
|
|
90
90
|
else
|
|
91
91
|
# Instantiate a homogeneous set
|
|
92
|
-
result_set.map { |record| instantiate_instance_of(self, record, column_types, &block) }
|
|
92
|
+
result_set.indexed_rows.map { |record| instantiate_instance_of(self, record, column_types, &block) }
|
|
93
93
|
end
|
|
94
94
|
end
|
|
95
95
|
end
|
|
@@ -184,30 +184,6 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
|
184
184
|
end
|
|
185
185
|
end
|
|
186
186
|
|
|
187
|
-
initializer "active_record.warn_on_records_fetched_greater_than" do
|
|
188
|
-
if config.active_record.warn_on_records_fetched_greater_than
|
|
189
|
-
ActiveRecord.deprecator.warn <<~MSG.squish
|
|
190
|
-
`config.active_record.warn_on_records_fetched_greater_than` is deprecated and will be
|
|
191
|
-
removed in Rails 8.0.
|
|
192
|
-
Please subscribe to `sql.active_record` notifications and access the row count field to
|
|
193
|
-
detect large result set sizes.
|
|
194
|
-
MSG
|
|
195
|
-
ActiveSupport.on_load(:active_record) do
|
|
196
|
-
require "active_record/relation/record_fetch_warning"
|
|
197
|
-
end
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
initializer "active_record.sqlite3_deprecated_warning" do
|
|
202
|
-
if config.active_record.key?(:sqlite3_production_warning)
|
|
203
|
-
config.active_record.delete(:sqlite3_production_warning)
|
|
204
|
-
ActiveRecord.deprecator.warn <<~MSG.squish
|
|
205
|
-
The `config.active_record.sqlite3_production_warning` configuration no longer has any effect
|
|
206
|
-
and can be safely removed.
|
|
207
|
-
MSG
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
|
-
|
|
211
187
|
initializer "active_record.sqlite3_adapter_strict_strings_by_default" do
|
|
212
188
|
config.after_initialize do
|
|
213
189
|
if config.active_record.sqlite3_adapter_strict_strings_by_default
|
|
@@ -390,7 +366,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
|
390
366
|
config.after_initialize do
|
|
391
367
|
if app.config.active_record.query_log_tags_enabled
|
|
392
368
|
ActiveRecord.query_transformers << ActiveRecord::QueryLogs
|
|
393
|
-
ActiveRecord::QueryLogs.taggings.merge
|
|
369
|
+
ActiveRecord::QueryLogs.taggings = ActiveRecord::QueryLogs.taggings.merge(
|
|
394
370
|
application: Rails.application.class.name.split("::").first,
|
|
395
371
|
pid: -> { Process.pid.to_s },
|
|
396
372
|
socket: ->(context) { context[:connection].pool.db_config.socket },
|
|
@@ -405,7 +381,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
|
405
381
|
end
|
|
406
382
|
|
|
407
383
|
if app.config.active_record.query_log_tags_format
|
|
408
|
-
ActiveRecord::QueryLogs.
|
|
384
|
+
ActiveRecord::QueryLogs.tags_formatter = app.config.active_record.query_log_tags_format
|
|
409
385
|
end
|
|
410
386
|
|
|
411
387
|
if app.config.active_record.cache_query_log_tags
|
|
@@ -87,22 +87,7 @@ db_namespace = namespace :db do
|
|
|
87
87
|
|
|
88
88
|
desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
|
|
89
89
|
task migrate: :load_config do
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if db_configs.size == 1 && db_configs.first.primary?
|
|
93
|
-
ActiveRecord::Tasks::DatabaseTasks.migrate
|
|
94
|
-
else
|
|
95
|
-
mapped_versions = ActiveRecord::Tasks::DatabaseTasks.db_configs_with_versions
|
|
96
|
-
|
|
97
|
-
mapped_versions.sort.each do |version, db_configs|
|
|
98
|
-
db_configs.each do |db_config|
|
|
99
|
-
ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection(db_config) do
|
|
100
|
-
ActiveRecord::Tasks::DatabaseTasks.migrate(version)
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
90
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate_all
|
|
106
91
|
db_namespace["_dump"].invoke
|
|
107
92
|
end
|
|
108
93
|
|
|
@@ -175,8 +160,8 @@ db_namespace = namespace :db do
|
|
|
175
160
|
end
|
|
176
161
|
end
|
|
177
162
|
|
|
178
|
-
|
|
179
|
-
task reset: ["db:drop", "db:create", "db:migrate"]
|
|
163
|
+
desc "Resets your database using your migrations for the current environment"
|
|
164
|
+
task reset: ["db:drop", "db:create", "db:schema:dump", "db:migrate"]
|
|
180
165
|
|
|
181
166
|
desc 'Run the "up" for a given migration VERSION.'
|
|
182
167
|
task up: :load_config do
|
|
@@ -462,19 +447,14 @@ db_namespace = namespace :db do
|
|
|
462
447
|
namespace :schema do
|
|
463
448
|
desc "Create a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`)"
|
|
464
449
|
task dump: :load_config do
|
|
465
|
-
ActiveRecord::Tasks::DatabaseTasks.
|
|
466
|
-
db_config = pool.db_config
|
|
467
|
-
schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
|
|
468
|
-
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, schema_format)
|
|
469
|
-
end
|
|
450
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_all
|
|
470
451
|
|
|
471
452
|
db_namespace["schema:dump"].reenable
|
|
472
453
|
end
|
|
473
454
|
|
|
474
455
|
desc "Load a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`) into the database"
|
|
475
456
|
task load: [:load_config, :check_protected_environments] do
|
|
476
|
-
|
|
477
|
-
ActiveRecord::Tasks::DatabaseTasks.load_schema_current(schema_format, ENV["SCHEMA"])
|
|
457
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema_current(ENV["SCHEMA_FORMAT"], ENV["SCHEMA"])
|
|
478
458
|
end
|
|
479
459
|
|
|
480
460
|
namespace :dump do
|
|
@@ -483,8 +463,7 @@ db_namespace = namespace :db do
|
|
|
483
463
|
task name => :load_config do
|
|
484
464
|
ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(name: name) do |pool|
|
|
485
465
|
db_config = pool.db_config
|
|
486
|
-
|
|
487
|
-
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, schema_format)
|
|
466
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, ENV["SCHEMA_FORMAT"] || db_config.schema_format)
|
|
488
467
|
end
|
|
489
468
|
|
|
490
469
|
db_namespace["schema:dump:#{name}"].reenable
|
|
@@ -494,12 +473,11 @@ db_namespace = namespace :db do
|
|
|
494
473
|
|
|
495
474
|
namespace :load do
|
|
496
475
|
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
|
|
497
|
-
desc "Load a database schema file (either db/schema.rb or db/structure.sql, depending on
|
|
476
|
+
desc "Load a database schema file (either db/schema.rb or db/structure.sql, depending on configuration) into the #{name} database"
|
|
498
477
|
task name => "db:test:purge:#{name}" do
|
|
499
478
|
ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(name: name) do |pool|
|
|
500
479
|
db_config = pool.db_config
|
|
501
|
-
|
|
502
|
-
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
|
|
480
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, ENV["SCHEMA_FORMAT"] || db_config.schema_format)
|
|
503
481
|
end
|
|
504
482
|
end
|
|
505
483
|
end
|
|
@@ -543,13 +521,12 @@ db_namespace = namespace :db do
|
|
|
543
521
|
end
|
|
544
522
|
|
|
545
523
|
namespace :test do
|
|
546
|
-
# desc "Recreate the test database from an existent schema file (schema.rb or structure.sql, depending on
|
|
524
|
+
# desc "Recreate the test database from an existent schema file (schema.rb or structure.sql, depending on configuration)"
|
|
547
525
|
task load_schema: %w(db:test:purge) do
|
|
548
526
|
ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: "test") do |pool|
|
|
549
527
|
db_config = pool.db_config
|
|
550
528
|
ActiveRecord::Schema.verbose = false
|
|
551
|
-
|
|
552
|
-
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
|
|
529
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, ENV["SCHEMA_FORMAT"] || db_config.schema_format)
|
|
553
530
|
end
|
|
554
531
|
end
|
|
555
532
|
|
|
@@ -574,8 +551,7 @@ db_namespace = namespace :db do
|
|
|
574
551
|
ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: "test", name: name) do |pool|
|
|
575
552
|
db_config = pool.db_config
|
|
576
553
|
ActiveRecord::Schema.verbose = false
|
|
577
|
-
|
|
578
|
-
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
|
|
554
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, ENV["SCHEMA_FORMAT"] || db_config.schema_format)
|
|
579
555
|
end
|
|
580
556
|
end
|
|
581
557
|
end
|
|
@@ -198,7 +198,7 @@ module ActiveRecord
|
|
|
198
198
|
end
|
|
199
199
|
|
|
200
200
|
def join_scope(table, foreign_table, foreign_klass)
|
|
201
|
-
predicate_builder = predicate_builder(table)
|
|
201
|
+
predicate_builder = klass.predicate_builder.with(TableMetadata.new(klass, table))
|
|
202
202
|
scope_chain_items = join_scopes(table, predicate_builder)
|
|
203
203
|
klass_scope = klass_join_scope(table, predicate_builder)
|
|
204
204
|
|
|
@@ -224,7 +224,7 @@ module ActiveRecord
|
|
|
224
224
|
klass_scope
|
|
225
225
|
end
|
|
226
226
|
|
|
227
|
-
def join_scopes(table, predicate_builder, klass = self.klass, record = nil) # :nodoc:
|
|
227
|
+
def join_scopes(table, predicate_builder = nil, klass = self.klass, record = nil) # :nodoc:
|
|
228
228
|
if scope
|
|
229
229
|
[scope_for(build_scope(table, predicate_builder, klass), record)]
|
|
230
230
|
else
|
|
@@ -232,7 +232,7 @@ module ActiveRecord
|
|
|
232
232
|
end
|
|
233
233
|
end
|
|
234
234
|
|
|
235
|
-
def klass_join_scope(table, predicate_builder) # :nodoc:
|
|
235
|
+
def klass_join_scope(table, predicate_builder = nil) # :nodoc:
|
|
236
236
|
relation = build_scope(table, predicate_builder)
|
|
237
237
|
klass.scope_for_association(relation)
|
|
238
238
|
end
|
|
@@ -333,12 +333,8 @@ module ActiveRecord
|
|
|
333
333
|
collect_join_chain
|
|
334
334
|
end
|
|
335
335
|
|
|
336
|
-
def build_scope(table, predicate_builder =
|
|
337
|
-
Relation.create(
|
|
338
|
-
klass,
|
|
339
|
-
table: table,
|
|
340
|
-
predicate_builder: predicate_builder
|
|
341
|
-
)
|
|
336
|
+
def build_scope(table, predicate_builder = nil, klass = self.klass)
|
|
337
|
+
Relation.create(klass, table:, predicate_builder:)
|
|
342
338
|
end
|
|
343
339
|
|
|
344
340
|
def strict_loading?
|
|
@@ -357,10 +353,6 @@ module ActiveRecord
|
|
|
357
353
|
end
|
|
358
354
|
|
|
359
355
|
private
|
|
360
|
-
def predicate_builder(table)
|
|
361
|
-
PredicateBuilder.new(TableMetadata.new(klass, table))
|
|
362
|
-
end
|
|
363
|
-
|
|
364
356
|
def primary_key(klass)
|
|
365
357
|
klass.primary_key || raise(UnknownPrimaryKey.new(klass))
|
|
366
358
|
end
|
|
@@ -531,9 +523,9 @@ module ActiveRecord
|
|
|
531
523
|
@association_foreign_key = nil
|
|
532
524
|
@association_primary_key = nil
|
|
533
525
|
if options[:query_constraints]
|
|
534
|
-
|
|
535
|
-
Setting `query_constraints:` option on `#{active_record}.#{macro} :#{name}` is
|
|
536
|
-
To
|
|
526
|
+
raise ConfigurationError, <<~MSG.squish
|
|
527
|
+
Setting `query_constraints:` option on `#{active_record}.#{macro} :#{name}` is not allowed.
|
|
528
|
+
To get the same behavior, use the `foreign_key` option instead.
|
|
537
529
|
MSG
|
|
538
530
|
end
|
|
539
531
|
|
|
@@ -562,12 +554,12 @@ module ActiveRecord
|
|
|
562
554
|
def foreign_key(infer_from_inverse_of: true)
|
|
563
555
|
@foreign_key ||= if options[:foreign_key]
|
|
564
556
|
if options[:foreign_key].is_a?(Array)
|
|
565
|
-
options[:foreign_key].map { |fk| fk.to_s.freeze }.freeze
|
|
557
|
+
options[:foreign_key].map { |fk| -fk.to_s.freeze }.freeze
|
|
566
558
|
else
|
|
567
559
|
options[:foreign_key].to_s.freeze
|
|
568
560
|
end
|
|
569
561
|
elsif options[:query_constraints]
|
|
570
|
-
options[:query_constraints].map { |fk| fk.to_s.freeze }.freeze
|
|
562
|
+
options[:query_constraints].map { |fk| -fk.to_s.freeze }.freeze
|
|
571
563
|
else
|
|
572
564
|
derived_fk = derive_foreign_key(infer_from_inverse_of: infer_from_inverse_of)
|
|
573
565
|
|
|
@@ -575,7 +567,12 @@ module ActiveRecord
|
|
|
575
567
|
derived_fk = derive_fk_query_constraints(derived_fk)
|
|
576
568
|
end
|
|
577
569
|
|
|
578
|
-
derived_fk
|
|
570
|
+
if derived_fk.is_a?(Array)
|
|
571
|
+
derived_fk.map! { |fk| -fk.freeze }
|
|
572
|
+
derived_fk.freeze
|
|
573
|
+
else
|
|
574
|
+
-derived_fk.freeze
|
|
575
|
+
end
|
|
579
576
|
end
|
|
580
577
|
end
|
|
581
578
|
|
|
@@ -1065,7 +1062,7 @@ module ActiveRecord
|
|
|
1065
1062
|
source_reflection.scopes + super
|
|
1066
1063
|
end
|
|
1067
1064
|
|
|
1068
|
-
def join_scopes(table, predicate_builder, klass = self.klass, record = nil) # :nodoc:
|
|
1065
|
+
def join_scopes(table, predicate_builder = nil, klass = self.klass, record = nil) # :nodoc:
|
|
1069
1066
|
source_reflection.join_scopes(table, predicate_builder, klass, record) + super
|
|
1070
1067
|
end
|
|
1071
1068
|
|
|
@@ -1238,7 +1235,7 @@ module ActiveRecord
|
|
|
1238
1235
|
@previous_reflection = previous_reflection
|
|
1239
1236
|
end
|
|
1240
1237
|
|
|
1241
|
-
def join_scopes(table, predicate_builder, klass = self.klass, record = nil) # :nodoc:
|
|
1238
|
+
def join_scopes(table, predicate_builder = nil, klass = self.klass, record = nil) # :nodoc:
|
|
1242
1239
|
scopes = super
|
|
1243
1240
|
unless @previous_reflection.through_reflection?
|
|
1244
1241
|
scopes += @previous_reflection.join_scopes(table, predicate_builder, klass, record)
|
|
@@ -5,11 +5,12 @@ module ActiveRecord
|
|
|
5
5
|
class BatchEnumerator
|
|
6
6
|
include Enumerable
|
|
7
7
|
|
|
8
|
-
def initialize(of: 1000, start: nil, finish: nil, relation:, order: :asc, use_ranges: nil) # :nodoc:
|
|
8
|
+
def initialize(of: 1000, start: nil, finish: nil, relation:, cursor:, order: :asc, use_ranges: nil) # :nodoc:
|
|
9
9
|
@of = of
|
|
10
10
|
@relation = relation
|
|
11
11
|
@start = start
|
|
12
12
|
@finish = finish
|
|
13
|
+
@cursor = cursor
|
|
13
14
|
@order = order
|
|
14
15
|
@use_ranges = use_ranges
|
|
15
16
|
end
|
|
@@ -52,7 +53,7 @@ module ActiveRecord
|
|
|
52
53
|
def each_record(&block)
|
|
53
54
|
return to_enum(:each_record) unless block_given?
|
|
54
55
|
|
|
55
|
-
@relation.to_enum(:in_batches, of: @of, start: @start, finish: @finish, load: true, order: @order).each do |relation|
|
|
56
|
+
@relation.to_enum(:in_batches, of: @of, start: @start, finish: @finish, load: true, cursor: @cursor, order: @order).each do |relation|
|
|
56
57
|
relation.records.each(&block)
|
|
57
58
|
end
|
|
58
59
|
end
|
|
@@ -105,7 +106,7 @@ module ActiveRecord
|
|
|
105
106
|
# relation.update_all(awesome: true)
|
|
106
107
|
# end
|
|
107
108
|
def each(&block)
|
|
108
|
-
enum = @relation.to_enum(:in_batches, of: @of, start: @start, finish: @finish, load: false, order: @order, use_ranges: @use_ranges)
|
|
109
|
+
enum = @relation.to_enum(:in_batches, of: @of, start: @start, finish: @finish, load: false, cursor: @cursor, order: @order, use_ranges: @use_ranges)
|
|
109
110
|
return enum.each(&block) if block_given?
|
|
110
111
|
enum
|
|
111
112
|
end
|