Skip to content

Commit 9bb2512

Browse files
authored
Merge pull request rails#42445 from Shopify/active-record-cattr-2
Get rid of `mattr_accessor` in `ActiveRecord::Core`
2 parents 4814103 + ba877bd commit 9bb2512

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+368
-331
lines changed

activerecord/lib/active_record.rb

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,144 @@ module Tasks
172172
singleton_class.attr_accessor :legacy_connection_handling
173173
self.legacy_connection_handling = true
174174

175+
##
176+
# :singleton-method:
177+
# Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
178+
# dates and times from the database. This is set to :utc by default.
179+
singleton_class.attr_accessor :default_timezone
180+
self.default_timezone = :utc
181+
182+
singleton_class.attr_accessor :writing_role
183+
self.writing_role = :writing
184+
185+
singleton_class.attr_accessor :reading_role
186+
self.reading_role = :reading
187+
188+
# Sets the async_query_executor for an application. By default the thread pool executor
189+
# set to +nil+ which will not run queries in the background. Applications must configure
190+
# a thread pool executor to use this feature. Options are:
191+
#
192+
# * nil - Does not initialize a thread pool executor. Any async calls will be
193+
# run in the foreground.
194+
# * :global_thread_pool - Initializes a single +Concurrent::ThreadPoolExecutor+
195+
# that uses the +async_query_concurrency+ for the +max_threads+ value.
196+
# * :multi_thread_pool - Initializes a +Concurrent::ThreadPoolExecutor+ for each
197+
# database connection. The initializer values are defined in the configuration hash.
198+
singleton_class.attr_accessor :async_query_executor
199+
self.async_query_executor = nil
200+
201+
def self.global_thread_pool_async_query_executor # :nodoc:
202+
concurrency = global_executor_concurrency || 4
203+
@global_thread_pool_async_query_executor ||= Concurrent::ThreadPoolExecutor.new(
204+
min_threads: 0,
205+
max_threads: concurrency,
206+
max_queue: concurrency * 4,
207+
fallback_policy: :caller_runs
208+
)
209+
end
210+
211+
# Set the +global_executor_concurrency+. This configuration value can only be used
212+
# with the global thread pool async query executor.
213+
def self.global_executor_concurrency=(global_executor_concurrency)
214+
if self.async_query_executor.nil? || self.async_query_executor == :multi_thread_pool
215+
raise ArgumentError, "`global_executor_concurrency` cannot be set when using the executor is nil or set to multi_thead_pool. For multiple thread pools, please set the concurrency in your database configuration."
216+
end
217+
218+
@global_executor_concurrency = global_executor_concurrency
219+
end
220+
221+
def self.global_executor_concurrency # :nodoc:
222+
@global_executor_concurrency ||= nil
223+
end
224+
225+
##
226+
# :singleton-method:
227+
#
228+
# Specifies if the methods calling database queries should be logged below
229+
# their relevant queries. Defaults to false.
230+
singleton_class.attr_accessor :verbose_query_logs
231+
self.verbose_query_logs = false
232+
233+
##
234+
# :singleton-method:
235+
#
236+
# Specifies the names of the queues used by background jobs.
237+
singleton_class.attr_accessor :queues
238+
self.queues = {}
239+
240+
singleton_class.attr_accessor :maintain_test_schema
241+
self.maintain_test_schema = nil
242+
243+
##
244+
# :singleton-method:
245+
# Specify a threshold for the size of query result sets. If the number of
246+
# records in the set exceeds the threshold, a warning is logged. This can
247+
# be used to identify queries which load thousands of records and
248+
# potentially cause memory bloat.
249+
singleton_class.attr_accessor :warn_on_records_fetched_greater_than
250+
self.warn_on_records_fetched_greater_than = false
251+
252+
singleton_class.attr_accessor :application_record_class
253+
self.application_record_class = nil
254+
255+
##
256+
# :singleton-method:
257+
# Set the application to log or raise when an association violates strict loading.
258+
# Defaults to :raise.
259+
singleton_class.attr_accessor :action_on_strict_loading_violation
260+
self.action_on_strict_loading_violation = :raise
261+
262+
##
263+
# :singleton-method:
264+
# Specifies the format to use when dumping the database schema with Rails'
265+
# Rakefile. If :sql, the schema is dumped as (potentially database-
266+
# specific) SQL statements. If :ruby, the schema is dumped as an
267+
# ActiveRecord::Schema file which can be loaded into any database that
268+
# supports migrations. Use :ruby if you want to have different database
269+
# adapters for, e.g., your development and test environments.
270+
singleton_class.attr_accessor :schema_format
271+
self.schema_format = :ruby
272+
273+
##
274+
# :singleton-method:
275+
# Specifies if an error should be raised if the query has an order being
276+
# ignored when doing batch queries. Useful in applications where the
277+
# scope being ignored is error-worthy, rather than a warning.
278+
singleton_class.attr_accessor :error_on_ignored_order
279+
self.error_on_ignored_order = false
280+
281+
##
282+
# :singleton-method:
283+
# Specify whether or not to use timestamps for migration versions
284+
singleton_class.attr_accessor :timestamped_migrations
285+
self.timestamped_migrations = true
286+
287+
##
288+
# :singleton-method:
289+
# Specify whether schema dump should happen at the end of the
290+
# bin/rails db:migrate command. This is true by default, which is useful for the
291+
# development environment. This should ideally be false in the production
292+
# environment where dumping schema is rarely needed.
293+
singleton_class.attr_accessor :dump_schema_after_migration
294+
self.dump_schema_after_migration = true
295+
296+
##
297+
# :singleton-method:
298+
# Specifies which database schemas to dump when calling db:schema:dump.
299+
# If the value is :schema_search_path (the default), any schemas listed in
300+
# schema_search_path are dumped. Use :all to dump all schemas regardless
301+
# of schema_search_path, or a string of comma separated schemas for a
302+
# custom list.
303+
singleton_class.attr_accessor :dump_schemas
304+
self.dump_schemas = :schema_search_path
305+
306+
##
307+
# :singleton-method:
308+
# Show a warning when Rails couldn't parse your database.yml
309+
# for multiple databases.
310+
singleton_class.attr_accessor :suppress_multiple_database_warning
311+
self.suppress_multiple_database_warning = false
312+
175313
def self.eager_load!
176314
super
177315
ActiveRecord::Locking.eager_load!

activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ def schedule_query(future_result) # :nodoc:
460460

461461
private
462462
def build_async_executor
463-
case Base.async_query_executor
463+
case ActiveRecord.async_query_executor
464464
when :multi_thread_pool
465465
if @db_config.max_threads > 0
466466
Concurrent::ThreadPoolExecutor.new(
@@ -471,7 +471,7 @@ def build_async_executor
471471
)
472472
end
473473
when :global_thread_pool
474-
Base.global_thread_pool_async_query_executor
474+
ActiveRecord.global_thread_pool_async_query_executor
475475
end
476476
end
477477

activerecord/lib/active_record/connection_adapters/abstract/quoting.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def unquoted_false
113113
# if the value is a Time responding to usec.
114114
def quoted_date(value)
115115
if value.acts_like?(:time)
116-
if ActiveRecord::Base.default_timezone == :utc
116+
if ActiveRecord.default_timezone == :utc
117117
value = value.getutc if !value.utc?
118118
else
119119
value = value.getlocal

activerecord/lib/active_record/connection_adapters/abstract_adapter.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ def supports_concurrent_connections?
443443

444444
def async_enabled? # :nodoc:
445445
supports_concurrent_connections? &&
446-
!Base.async_query_executor.nil? && !pool.async_executor.nil?
446+
!ActiveRecord.async_query_executor.nil? && !pool.async_executor.nil?
447447
end
448448

449449
# This is meant to be implemented by the adapters that support extensions

activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ def explain(arel, binds = [])
4141
def execute(sql, name = nil, async: false)
4242
check_if_write_query(sql)
4343

44-
# make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
44+
# make sure we carry over any changes to ActiveRecord.default_timezone that have been
4545
# made since we established the connection
46-
@connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
46+
@connection.query_options[:database_timezone] = ActiveRecord.default_timezone
4747

4848
super
4949
end
@@ -152,9 +152,9 @@ def exec_stmt_and_free(sql, name, binds, cache_stmt: false, async: false)
152152
materialize_transactions
153153
mark_transaction_written_if_write(sql)
154154

155-
# make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
155+
# make sure we carry over any changes to ActiveRecord.default_timezone that have been
156156
# made since we established the connection
157-
@connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
157+
@connection.query_options[:database_timezone] = ActiveRecord.default_timezone
158158

159159
type_casted_binds = type_casted_binds(binds)
160160

activerecord/lib/active_record/connection_adapters/mysql/quoting.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def _type_cast(value)
7979
# We need to check explicitly for ActiveSupport::TimeWithZone because
8080
# we need to transform it to Time objects but we don't want to
8181
# transform Time objects to themselves.
82-
if ActiveRecord::Base.default_timezone == :utc
82+
if ActiveRecord.default_timezone == :utc
8383
value.getutc
8484
else
8585
value.getlocal

activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ def exec_no_cache(sql, name, binds, async: false)
696696
materialize_transactions
697697
mark_transaction_written_if_write(sql)
698698

699-
# make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
699+
# make sure we carry over any changes to ActiveRecord.default_timezone that have been
700700
# made since we established the connection
701701
update_typemap_for_default_timezone
702702

@@ -810,7 +810,7 @@ def configure_connection
810810
# If using Active Record's time zone support configure the connection to return
811811
# TIMESTAMP WITH ZONE types in UTC.
812812
unless variables["timezone"]
813-
if ActiveRecord::Base.default_timezone == :utc
813+
if ActiveRecord.default_timezone == :utc
814814
variables["timezone"] = "UTC"
815815
elsif @local_tz
816816
variables["timezone"] = @local_tz

activerecord/lib/active_record/connection_handling.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ def connected_to_many(*classes, role:, shard: nil, prevent_writes: false)
184184
raise NotImplementedError, "connected_to_many can only be called on ActiveRecord::Base."
185185
end
186186

187-
prevent_writes = true if role == reading_role
187+
prevent_writes = true if role == ActiveRecord.reading_role
188188

189189
connected_to_stack << { role: role, shard: shard, prevent_writes: prevent_writes, klasses: classes }
190190
yield
@@ -204,7 +204,7 @@ def connecting_to(role: default_role, shard: default_shard, prevent_writes: fals
204204
raise NotImplementedError, "`connecting_to` is not available with `legacy_connection_handling`."
205205
end
206206

207-
prevent_writes = true if role == reading_role
207+
prevent_writes = true if role == ActiveRecord.reading_role
208208

209209
self.connected_to_stack << { role: role, shard: shard, prevent_writes: prevent_writes, klasses: [self] }
210210
end
@@ -240,7 +240,7 @@ def connected_to?(role:, shard: ActiveRecord::Base.default_shard)
240240

241241
def lookup_connection_handler(handler_key) # :nodoc:
242242
if ActiveRecord.legacy_connection_handling
243-
handler_key ||= ActiveRecord::Base.writing_role
243+
handler_key ||= ActiveRecord.writing_role
244244
connection_handlers[handler_key] ||= ActiveRecord::ConnectionAdapters::ConnectionHandler.new
245245
else
246246
ActiveRecord::Base.connection_handler
@@ -356,7 +356,7 @@ def with_handler(handler_key, &blk)
356356
end
357357

358358
def with_role_and_shard(role, shard, prevent_writes)
359-
prevent_writes = true if role == reading_role
359+
prevent_writes = true if role == ActiveRecord.reading_role
360360

361361
if ActiveRecord.legacy_connection_handling
362362
with_handler(role.to_sym) do

0 commit comments

Comments
 (0)