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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +67 -0
  3. data/lib/active_record/associations/has_many_through_association.rb +7 -1
  4. data/lib/active_record/attribute_methods/primary_key.rb +2 -7
  5. data/lib/active_record/attribute_methods/time_zone_conversion.rb +2 -12
  6. data/lib/active_record/callbacks.rb +1 -1
  7. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +26 -8
  8. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -5
  9. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +6 -1
  10. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +8 -2
  11. data/lib/active_record/connection_adapters/abstract_adapter.rb +0 -1
  12. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +8 -4
  13. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  14. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -4
  15. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +0 -10
  16. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -11
  17. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +1 -1
  18. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +4 -8
  19. data/lib/active_record/connection_adapters/postgresql_adapter.rb +8 -8
  20. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +1 -1
  21. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +0 -2
  22. data/lib/active_record/connection_adapters.rb +0 -56
  23. data/lib/active_record/core.rb +14 -11
  24. data/lib/active_record/enum.rb +54 -72
  25. data/lib/active_record/fixtures.rb +0 -1
  26. data/lib/active_record/gem_version.rb +1 -1
  27. data/lib/active_record/locking/optimistic.rb +1 -1
  28. data/lib/active_record/log_subscriber.rb +5 -11
  29. data/lib/active_record/marshalling.rb +4 -1
  30. data/lib/active_record/migration.rb +0 -5
  31. data/lib/active_record/model_schema.rb +2 -3
  32. data/lib/active_record/query_cache.rb +0 -4
  33. data/lib/active_record/query_logs.rb +5 -11
  34. data/lib/active_record/querying.rb +2 -2
  35. data/lib/active_record/railtie.rb +1 -24
  36. data/lib/active_record/railties/databases.rake +1 -1
  37. data/lib/active_record/reflection.rb +14 -19
  38. data/lib/active_record/relation/calculations.rb +24 -28
  39. data/lib/active_record/relation/predicate_builder.rb +8 -0
  40. data/lib/active_record/relation/query_methods.rb +66 -36
  41. data/lib/active_record/relation.rb +8 -1
  42. data/lib/active_record/result.rb +10 -9
  43. data/lib/active_record/table_metadata.rb +1 -3
  44. data/lib/active_record/tasks/database_tasks.rb +4 -31
  45. data/lib/active_record/testing/query_assertions.rb +2 -2
  46. data/lib/active_record.rb +0 -45
  47. data/lib/arel/table.rb +3 -7
  48. data/lib/arel/visitors/sqlite.rb +25 -0
  49. metadata +9 -10
  50. data/lib/active_record/relation/record_fetch_warning.rb +0 -52
@@ -506,7 +506,7 @@ module ActiveRecord
506
506
  #
507
507
  # Post.with_recursive(post_and_replies: [Post.where(id: 42), Post.joins('JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id')])
508
508
  # # => ActiveRecord::Relation
509
- # # WITH post_and_replies AS (
509
+ # # WITH RECURSIVE post_and_replies AS (
510
510
  # # (SELECT * FROM posts WHERE id = 42)
511
511
  # # UNION ALL
512
512
  # # (SELECT * FROM posts JOIN posts_and_replies ON posts.in_reply_to_id = posts_and_replies.id)
@@ -1656,6 +1656,22 @@ module ActiveRecord
1656
1656
  self
1657
1657
  end
1658
1658
 
1659
+ protected
1660
+ def arel_columns(columns)
1661
+ columns.flat_map do |field|
1662
+ case field
1663
+ when Symbol, String
1664
+ arel_column(field)
1665
+ when Proc
1666
+ field.call
1667
+ when Hash
1668
+ arel_columns_from_hash(field)
1669
+ else
1670
+ field
1671
+ end
1672
+ end
1673
+ end
1674
+
1659
1675
  private
1660
1676
  def async
1661
1677
  spawn.async!
@@ -1910,12 +1926,26 @@ module ActiveRecord
1910
1926
  end
1911
1927
  end
1912
1928
 
1913
- def build_with_expression_from_value(value)
1929
+ def build_with_expression_from_value(value, nested = false)
1914
1930
  case value
1915
1931
  when Arel::Nodes::SqlLiteral then Arel::Nodes::Grouping.new(value)
1916
- when ActiveRecord::Relation then value.arel
1932
+ when ActiveRecord::Relation
1933
+ if nested
1934
+ value.arel.ast
1935
+ else
1936
+ value.arel
1937
+ end
1917
1938
  when Arel::SelectManager then value
1918
- when Array then value.map { |q| build_with_expression_from_value(q) }.reduce { |result, value| result.union(:all, value) }
1939
+ when Array
1940
+ return build_with_expression_from_value(value.first, false) if value.size == 1
1941
+
1942
+ parts = value.map do |query|
1943
+ build_with_expression_from_value(query, true)
1944
+ end
1945
+
1946
+ parts.reduce do |result, value|
1947
+ Arel::Nodes::UnionAll.new(result, value)
1948
+ end
1919
1949
  else
1920
1950
  raise ArgumentError, "Unsupported argument type: `#{value}` #{value.class}"
1921
1951
  end
@@ -1929,38 +1959,43 @@ module ActiveRecord
1929
1959
  ).join_sources.first
1930
1960
  end
1931
1961
 
1932
- def arel_columns(columns)
1933
- columns.flat_map do |field|
1934
- case field
1935
- when Symbol
1936
- arel_column(field.to_s) do |attr_name|
1937
- model.adapter_class.quote_table_name(attr_name)
1962
+ def arel_columns_from_hash(fields)
1963
+ fields.flat_map do |table_name, columns|
1964
+ table_name = table_name.name if table_name.is_a?(Symbol)
1965
+ case columns
1966
+ when Symbol, String
1967
+ arel_column_with_table(table_name, columns.to_s)
1968
+ when Array
1969
+ columns.map do |column|
1970
+ arel_column_with_table(table_name, column.to_s)
1938
1971
  end
1939
- when String
1940
- arel_column(field, &:itself)
1941
- when Proc
1942
- field.call
1943
- when Hash
1944
- arel_columns_from_hash(field)
1945
1972
  else
1946
- field
1973
+ raise TypeError, "Expected Symbol, String or Array, got: #{columns.class}"
1947
1974
  end
1948
1975
  end
1949
1976
  end
1950
1977
 
1978
+ def arel_column_with_table(table_name, column_name)
1979
+ self.references_values |= [Arel.sql(table_name, retryable: true)]
1980
+ predicate_builder.resolve_arel_attribute(table_name, column_name) do
1981
+ lookup_table_klass_from_join_dependencies(table_name)
1982
+ end
1983
+ end
1984
+
1951
1985
  def arel_column(field)
1986
+ field = field.name if is_symbol = field.is_a?(Symbol)
1987
+
1952
1988
  field = model.attribute_aliases[field] || field
1953
1989
  from = from_clause.name || from_clause.value
1954
1990
 
1955
1991
  if model.columns_hash.key?(field) && (!from || table_name_matches?(from))
1956
1992
  table[field]
1957
- elsif field.match?(/\A\w+\.\w+\z/)
1958
- table, column = field.split(".")
1959
- predicate_builder.resolve_arel_attribute(table, column) do
1960
- lookup_table_klass_from_join_dependencies(table)
1961
- end
1962
- else
1993
+ elsif /\A(?<table>(?:\w+\.)?\w+)\.(?<column>\w+)\z/ =~ field
1994
+ arel_column_with_table(table, column)
1995
+ elsif block_given?
1963
1996
  yield field
1997
+ else
1998
+ Arel.sql(is_symbol ? model.adapter_class.quote_table_name(field) : field)
1964
1999
  end
1965
2000
  end
1966
2001
 
@@ -2182,34 +2217,29 @@ module ActiveRecord
2182
2217
  def process_select_args(fields)
2183
2218
  fields.flat_map do |field|
2184
2219
  if field.is_a?(Hash)
2185
- arel_columns_from_hash(field)
2220
+ arel_column_aliases_from_hash(field)
2186
2221
  else
2187
2222
  field
2188
2223
  end
2189
2224
  end
2190
2225
  end
2191
2226
 
2192
- def arel_columns_from_hash(fields)
2227
+ def arel_column_aliases_from_hash(fields)
2193
2228
  fields.flat_map do |key, columns_aliases|
2229
+ table_name = key.is_a?(Symbol) ? key.name : key
2194
2230
  case columns_aliases
2195
2231
  when Hash
2196
2232
  columns_aliases.map do |column, column_alias|
2197
- if values[:joins]&.include?(key)
2198
- references = PredicateBuilder.references({ key.to_s => fields[key] })
2199
- self.references_values |= references unless references.empty?
2200
- end
2201
- arel_column("#{key}.#{column}") do
2202
- predicate_builder.resolve_arel_attribute(key.to_s, column)
2203
- end.as(column_alias.to_s)
2233
+ arel_column_with_table(table_name, column.to_s)
2234
+ .as(model.adapter_class.quote_column_name(column_alias.to_s))
2204
2235
  end
2205
2236
  when Array
2206
2237
  columns_aliases.map do |column|
2207
- arel_column("#{key}.#{column}", &:itself)
2238
+ arel_column_with_table(table_name, column.to_s)
2208
2239
  end
2209
2240
  when String, Symbol
2210
- arel_column(key.to_s) do
2211
- predicate_builder.resolve_arel_attribute(model.table_name, key.to_s)
2212
- end.as(columns_aliases.to_s)
2241
+ arel_column(key)
2242
+ .as(model.adapter_class.quote_column_name(columns_aliases.to_s))
2213
2243
  end
2214
2244
  end
2215
2245
  end
@@ -74,7 +74,14 @@ module ActiveRecord
74
74
  alias :loaded? :loaded
75
75
  alias :locked? :lock_value
76
76
 
77
- def initialize(model, table: model.arel_table, predicate_builder: model.predicate_builder, values: {})
77
+ def initialize(model, table: nil, predicate_builder: nil, values: {})
78
+ if table
79
+ predicate_builder ||= model.predicate_builder.with(TableMetadata.new(model, table))
80
+ else
81
+ table = model.arel_table
82
+ predicate_builder ||= model.predicate_builder
83
+ end
84
+
78
85
  @model = model
79
86
  @table = table
80
87
  @values = values
@@ -127,9 +127,9 @@ module ActiveRecord
127
127
  # Returns an +Enumerator+ if no block is given.
128
128
  def each(&block)
129
129
  if block_given?
130
- indexed_rows.each(&block)
130
+ hash_rows.each(&block)
131
131
  else
132
- indexed_rows.to_enum { @rows.size }
132
+ hash_rows.to_enum { @rows.size }
133
133
  end
134
134
  end
135
135
 
@@ -191,6 +191,7 @@ module ActiveRecord
191
191
  def initialize_copy(other)
192
192
  @rows = rows.dup
193
193
  @column_types = column_types.dup
194
+ @hash_rows = nil
194
195
  end
195
196
 
196
197
  def freeze # :nodoc:
@@ -212,6 +213,13 @@ module ActiveRecord
212
213
  end
213
214
  end
214
215
 
216
+ def indexed_rows # :nodoc:
217
+ @indexed_rows ||= begin
218
+ columns = column_indexes
219
+ @rows.map { |row| IndexedRow.new(columns, row) }.freeze
220
+ end
221
+ end
222
+
215
223
  private
216
224
  def column_type(name, index, type_overrides)
217
225
  type_overrides.fetch(name) do
@@ -221,13 +229,6 @@ module ActiveRecord
221
229
  end
222
230
  end
223
231
 
224
- def indexed_rows
225
- @indexed_rows ||= begin
226
- columns = column_indexes
227
- @rows.map { |row| IndexedRow.new(columns, row) }.freeze
228
- end
229
- end
230
-
231
232
  def hash_rows
232
233
  # We use transform_values to rows.
233
234
  # This is faster because we avoid any reallocs and avoid hashing entirely.
@@ -69,9 +69,7 @@ module ActiveRecord
69
69
 
70
70
  def predicate_builder
71
71
  if klass
72
- predicate_builder = klass.predicate_builder.dup
73
- predicate_builder.instance_variable_set(:@table, self)
74
- predicate_builder
72
+ klass.predicate_builder.with(self)
75
73
  else
76
74
  PredicateBuilder.new(self)
77
75
  end
@@ -446,26 +446,10 @@ module ActiveRecord
446
446
  end
447
447
  end
448
448
 
449
- def cache_dump_filename(db_config_or_name, schema_cache_path: nil)
450
- if db_config_or_name.is_a?(DatabaseConfigurations::DatabaseConfig)
451
- schema_cache_path ||
452
- db_config_or_name.schema_cache_path ||
453
- schema_cache_env ||
454
- db_config_or_name.default_schema_cache_path(ActiveRecord::Tasks::DatabaseTasks.db_dir)
455
- else
456
- ActiveRecord.deprecator.warn(<<~MSG.squish)
457
- Passing a database name to `cache_dump_filename` is deprecated and will be removed in Rails 8.0. Pass a
458
- `ActiveRecord::DatabaseConfigurations::DatabaseConfig` object instead.
459
- MSG
460
-
461
- filename = if ActiveRecord::Base.configurations.primary?(db_config_or_name)
462
- "schema_cache.yml"
463
- else
464
- "#{db_config_or_name}_schema_cache.yml"
465
- end
466
-
467
- schema_cache_path || schema_cache_env || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
468
- end
449
+ def cache_dump_filename(db_config, schema_cache_path: nil)
450
+ schema_cache_path ||
451
+ db_config.schema_cache_path ||
452
+ db_config.default_schema_cache_path(ActiveRecord::Tasks::DatabaseTasks.db_dir)
469
453
  end
470
454
 
471
455
  def load_schema_current(format = ActiveRecord.schema_format, file = nil, environment = env)
@@ -536,17 +520,6 @@ module ActiveRecord
536
520
  end
537
521
 
538
522
  private
539
- def schema_cache_env
540
- if ENV["SCHEMA_CACHE"]
541
- ActiveRecord.deprecator.warn(<<~MSG.squish)
542
- Setting `ENV["SCHEMA_CACHE"]` is deprecated and will be removed in Rails 8.0.
543
- Configure the `:schema_cache_path` in the database configuration instead.
544
- MSG
545
-
546
- nil
547
- end
548
- end
549
-
550
523
  def with_temporary_pool(db_config, clobber: false)
551
524
  original_db_config = migration_class.connection_db_config
552
525
  pool = migration_class.connection_handler.establish_connection(db_config, clobber: clobber)
@@ -52,7 +52,7 @@ module ActiveRecord
52
52
  # assert_queries_match(/LIMIT \?/) { Post.first }
53
53
  #
54
54
  # If the +:include_schema+ option is provided, any queries (including schema related)
55
- # that match the matcher are considered.
55
+ # that match the matcher are considered.
56
56
  #
57
57
  # assert_queries_match(/FROM pg_attribute/i, include_schema: true) { Post.columns }
58
58
  #
@@ -80,7 +80,7 @@ module ActiveRecord
80
80
  # assert_no_queries_match(/SELECT/i) { post.comments }
81
81
  #
82
82
  # If the +:include_schema+ option is provided, any queries (including schema related)
83
- # that match the matcher are counted.
83
+ # that match the matcher are counted.
84
84
  #
85
85
  # assert_no_queries_match(/FROM pg_attribute/i, include_schema: true) { Post.columns }
86
86
  #
data/lib/active_record.rb CHANGED
@@ -268,14 +268,6 @@ module ActiveRecord
268
268
  singleton_class.attr_accessor :reading_role
269
269
  self.reading_role = :reading
270
270
 
271
- def self.legacy_connection_handling=(_)
272
- raise ArgumentError, <<~MSG.squish
273
- The `legacy_connection_handling` setter was deprecated in 7.0 and removed in 7.1,
274
- but is still defined in your configuration. Please remove this call as it no longer
275
- has any effect."
276
- MSG
277
- end
278
-
279
271
  ##
280
272
  # :singleton-method: async_query_executor
281
273
  # Sets the async_query_executor for an application. By default the thread pool executor
@@ -359,29 +351,6 @@ module ActiveRecord
359
351
  singleton_class.attr_accessor :run_after_transaction_callbacks_in_order_defined
360
352
  self.run_after_transaction_callbacks_in_order_defined = false
361
353
 
362
- def self.commit_transaction_on_non_local_return
363
- ActiveRecord.deprecator.warn <<-WARNING.squish
364
- `Rails.application.config.active_record.commit_transaction_on_non_local_return`
365
- is deprecated and will be removed in Rails 8.0.
366
- WARNING
367
- end
368
-
369
- def self.commit_transaction_on_non_local_return=(value)
370
- ActiveRecord.deprecator.warn <<-WARNING.squish
371
- `Rails.application.config.active_record.commit_transaction_on_non_local_return`
372
- is deprecated and will be removed in Rails 8.0.
373
- WARNING
374
- end
375
-
376
- ##
377
- # :singleton-method: warn_on_records_fetched_greater_than
378
- # Specify a threshold for the size of query result sets. If the number of
379
- # records in the set exceeds the threshold, a warning is logged. This can
380
- # be used to identify queries which load thousands of records and
381
- # potentially cause memory bloat.
382
- singleton_class.attr_accessor :warn_on_records_fetched_greater_than
383
- self.warn_on_records_fetched_greater_than = false
384
-
385
354
  singleton_class.attr_accessor :application_record_class
386
355
  self.application_record_class = nil
387
356
 
@@ -459,20 +428,6 @@ module ActiveRecord
459
428
  singleton_class.attr_accessor :verify_foreign_keys_for_fixtures
460
429
  self.verify_foreign_keys_for_fixtures = false
461
430
 
462
- def self.allow_deprecated_singular_associations_name
463
- ActiveRecord.deprecator.warn <<-WARNING.squish
464
- `Rails.application.config.active_record.allow_deprecated_singular_associations_name`
465
- is deprecated and will be removed in Rails 8.0.
466
- WARNING
467
- end
468
-
469
- def self.allow_deprecated_singular_associations_name=(value)
470
- ActiveRecord.deprecator.warn <<-WARNING.squish
471
- `Rails.application.config.active_record.allow_deprecated_singular_associations_name`
472
- is deprecated and will be removed in Rails 8.0.
473
- WARNING
474
- end
475
-
476
431
  singleton_class.attr_accessor :query_transformers
477
432
  self.query_transformers = []
478
433
 
data/lib/arel/table.rb CHANGED
@@ -12,13 +12,9 @@ module Arel # :nodoc: all
12
12
  attr_reader :table_alias
13
13
 
14
14
  def initialize(name, as: nil, klass: nil, type_caster: klass&.type_caster)
15
- @name =
16
- case name
17
- when Symbol then name.to_s
18
- else
19
- name
20
- end
15
+ name = name.name if name.is_a?(Symbol)
21
16
 
17
+ @name = name
22
18
  @klass = klass
23
19
  @type_caster = type_caster
24
20
 
@@ -84,7 +80,7 @@ module Arel # :nodoc: all
84
80
  end
85
81
 
86
82
  def [](name, table = self)
87
- name = name.to_s if name.is_a?(Symbol)
83
+ name = name.name if name.is_a?(Symbol)
88
84
  name = @klass.attribute_aliases[name] || name if @klass
89
85
  Attribute.new(table, name)
90
86
  end
@@ -33,6 +33,31 @@ module Arel # :nodoc: all
33
33
  collector << " IS NOT "
34
34
  visit o.right, collector
35
35
  end
36
+
37
+ # Queries used in UNION should not be wrapped by parentheses,
38
+ # because it is an invalid syntax in SQLite.
39
+ def infix_value_with_paren(o, collector, value, suppress_parens = false)
40
+ collector << "( " unless suppress_parens
41
+
42
+ left = o.left.is_a?(Nodes::Grouping) ? o.left.expr : o.left
43
+ collector = if left.class == o.class
44
+ infix_value_with_paren(left, collector, value, true)
45
+ else
46
+ grouping_parentheses left, collector, false
47
+ end
48
+
49
+ collector << value
50
+
51
+ right = o.right.is_a?(Nodes::Grouping) ? o.right.expr : o.right
52
+ collector = if right.class == o.class
53
+ infix_value_with_paren(right, collector, value, true)
54
+ else
55
+ grouping_parentheses right, collector, false
56
+ end
57
+
58
+ collector << " )" unless suppress_parens
59
+ collector
60
+ end
36
61
  end
37
62
  end
38
63
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.0.0.beta1
4
+ version: 8.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-26 00:00:00.000000000 Z
11
+ date: 2024-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 8.0.0.beta1
19
+ version: 8.0.0.rc1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 8.0.0.beta1
26
+ version: 8.0.0.rc1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activemodel
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 8.0.0.beta1
33
+ version: 8.0.0.rc1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 8.0.0.beta1
40
+ version: 8.0.0.rc1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: timeout
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -318,7 +318,6 @@ files:
318
318
  - lib/active_record/relation/predicate_builder/relation_handler.rb
319
319
  - lib/active_record/relation/query_attribute.rb
320
320
  - lib/active_record/relation/query_methods.rb
321
- - lib/active_record/relation/record_fetch_warning.rb
322
321
  - lib/active_record/relation/spawn_methods.rb
323
322
  - lib/active_record/relation/where_clause.rb
324
323
  - lib/active_record/result.rb
@@ -476,10 +475,10 @@ licenses:
476
475
  - MIT
477
476
  metadata:
478
477
  bug_tracker_uri: https://github.com/rails/rails/issues
479
- changelog_uri: https://github.com/rails/rails/blob/v8.0.0.beta1/activerecord/CHANGELOG.md
480
- documentation_uri: https://api.rubyonrails.org/v8.0.0.beta1/
478
+ changelog_uri: https://github.com/rails/rails/blob/v8.0.0.rc1/activerecord/CHANGELOG.md
479
+ documentation_uri: https://api.rubyonrails.org/v8.0.0.rc1/
481
480
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
482
- source_code_uri: https://github.com/rails/rails/tree/v8.0.0.beta1/activerecord
481
+ source_code_uri: https://github.com/rails/rails/tree/v8.0.0.rc1/activerecord
483
482
  rubygems_mfa_required: 'true'
484
483
  post_install_message:
485
484
  rdoc_options:
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActiveRecord
4
- class Relation
5
- module RecordFetchWarning
6
- # Deprecated: subscribe to sql.active_record notifications and
7
- # access the row count field to detect large result set sizes.
8
- #
9
- # When this module is prepended to ActiveRecord::Relation and
10
- # +config.active_record.warn_on_records_fetched_greater_than+ is
11
- # set to an integer, if the number of records a query returns is
12
- # greater than the value of +warn_on_records_fetched_greater_than+,
13
- # a warning is logged. This allows for the detection of queries that
14
- # return a large number of records, which could cause memory bloat.
15
- #
16
- # In most cases, fetching large number of records can be performed
17
- # efficiently using the ActiveRecord::Batches methods.
18
- # See ActiveRecord::Batches for more information.
19
- def exec_queries
20
- QueryRegistry.reset
21
-
22
- super.tap do |records|
23
- if model.logger && ActiveRecord.warn_on_records_fetched_greater_than
24
- if records.length > ActiveRecord.warn_on_records_fetched_greater_than
25
- model.logger.warn "Query fetched #{records.size} #{@klass} records: #{QueryRegistry.queries.join(";")}"
26
- end
27
- end
28
- end
29
- end
30
-
31
- # :stopdoc:
32
- ActiveSupport::Notifications.subscribe("sql.active_record") do |*, payload|
33
- QueryRegistry.queries << payload[:sql]
34
- end
35
- # :startdoc:
36
-
37
- module QueryRegistry # :nodoc:
38
- extend self
39
-
40
- def queries
41
- ActiveSupport::IsolatedExecutionState[:active_record_query_registry] ||= []
42
- end
43
-
44
- def reset
45
- queries.clear
46
- end
47
- end
48
- end
49
- end
50
- end
51
-
52
- ActiveRecord::Relation.prepend ActiveRecord::Relation::RecordFetchWarning