activerecord 6.1.6 → 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.

Files changed (218) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +728 -1279
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/lib/active_record/aggregations.rb +1 -1
  6. data/lib/active_record/association_relation.rb +0 -10
  7. data/lib/active_record/associations/association.rb +31 -9
  8. data/lib/active_record/associations/association_scope.rb +1 -3
  9. data/lib/active_record/associations/belongs_to_association.rb +15 -4
  10. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
  11. data/lib/active_record/associations/builder/association.rb +8 -2
  12. data/lib/active_record/associations/builder/belongs_to.rb +19 -6
  13. data/lib/active_record/associations/builder/collection_association.rb +1 -1
  14. data/lib/active_record/associations/builder/has_many.rb +3 -2
  15. data/lib/active_record/associations/builder/has_one.rb +2 -1
  16. data/lib/active_record/associations/builder/singular_association.rb +2 -2
  17. data/lib/active_record/associations/collection_association.rb +14 -23
  18. data/lib/active_record/associations/collection_proxy.rb +8 -3
  19. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  20. data/lib/active_record/associations/has_many_association.rb +1 -1
  21. data/lib/active_record/associations/has_many_through_association.rb +2 -1
  22. data/lib/active_record/associations/has_one_association.rb +10 -7
  23. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  24. data/lib/active_record/associations/preloader/association.rb +161 -47
  25. data/lib/active_record/associations/preloader/batch.rb +51 -0
  26. data/lib/active_record/associations/preloader/branch.rb +147 -0
  27. data/lib/active_record/associations/preloader/through_association.rb +37 -11
  28. data/lib/active_record/associations/preloader.rb +46 -110
  29. data/lib/active_record/associations/singular_association.rb +8 -2
  30. data/lib/active_record/associations/through_association.rb +1 -1
  31. data/lib/active_record/associations.rb +76 -81
  32. data/lib/active_record/asynchronous_queries_tracker.rb +57 -0
  33. data/lib/active_record/attribute_assignment.rb +1 -1
  34. data/lib/active_record/attribute_methods/before_type_cast.rb +7 -2
  35. data/lib/active_record/attribute_methods/dirty.rb +41 -16
  36. data/lib/active_record/attribute_methods/primary_key.rb +2 -2
  37. data/lib/active_record/attribute_methods/query.rb +2 -2
  38. data/lib/active_record/attribute_methods/read.rb +7 -5
  39. data/lib/active_record/attribute_methods/serialization.rb +66 -12
  40. data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
  41. data/lib/active_record/attribute_methods/write.rb +7 -10
  42. data/lib/active_record/attribute_methods.rb +6 -9
  43. data/lib/active_record/attributes.rb +24 -35
  44. data/lib/active_record/autosave_association.rb +3 -18
  45. data/lib/active_record/base.rb +19 -1
  46. data/lib/active_record/callbacks.rb +2 -2
  47. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +312 -0
  48. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
  49. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
  50. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +31 -558
  51. data/lib/active_record/connection_adapters/abstract/database_statements.rb +45 -21
  52. data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
  53. data/lib/active_record/connection_adapters/abstract/quoting.rb +11 -4
  54. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
  55. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +30 -13
  56. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +60 -16
  57. data/lib/active_record/connection_adapters/abstract/transaction.rb +3 -3
  58. data/lib/active_record/connection_adapters/abstract_adapter.rb +112 -66
  59. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +96 -81
  60. data/lib/active_record/connection_adapters/mysql/database_statements.rb +33 -23
  61. data/lib/active_record/connection_adapters/mysql/quoting.rb +16 -1
  62. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +1 -1
  63. data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -6
  64. data/lib/active_record/connection_adapters/pool_config.rb +1 -3
  65. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +19 -14
  66. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
  67. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
  68. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
  69. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
  70. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  71. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +28 -0
  72. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  73. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  74. data/lib/active_record/connection_adapters/postgresql/quoting.rb +6 -6
  75. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +32 -0
  76. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +5 -1
  77. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +12 -12
  78. data/lib/active_record/connection_adapters/postgresql_adapter.rb +157 -100
  79. data/lib/active_record/connection_adapters/schema_cache.rb +36 -37
  80. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +23 -19
  81. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +4 -2
  82. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -30
  83. data/lib/active_record/connection_adapters.rb +6 -5
  84. data/lib/active_record/connection_handling.rb +20 -38
  85. data/lib/active_record/core.rb +111 -110
  86. data/lib/active_record/database_configurations/connection_url_resolver.rb +0 -1
  87. data/lib/active_record/database_configurations/database_config.rb +12 -0
  88. data/lib/active_record/database_configurations/hash_config.rb +27 -1
  89. data/lib/active_record/database_configurations/url_config.rb +2 -2
  90. data/lib/active_record/database_configurations.rb +17 -9
  91. data/lib/active_record/delegated_type.rb +33 -11
  92. data/lib/active_record/destroy_association_async_job.rb +1 -1
  93. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  94. data/lib/active_record/dynamic_matchers.rb +1 -1
  95. data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
  96. data/lib/active_record/encryption/cipher.rb +53 -0
  97. data/lib/active_record/encryption/config.rb +44 -0
  98. data/lib/active_record/encryption/configurable.rb +61 -0
  99. data/lib/active_record/encryption/context.rb +35 -0
  100. data/lib/active_record/encryption/contexts.rb +72 -0
  101. data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
  102. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  103. data/lib/active_record/encryption/encryptable_record.rb +208 -0
  104. data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
  105. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  106. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  107. data/lib/active_record/encryption/encryptor.rb +155 -0
  108. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  109. data/lib/active_record/encryption/errors.rb +15 -0
  110. data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
  111. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +29 -0
  112. data/lib/active_record/encryption/key.rb +28 -0
  113. data/lib/active_record/encryption/key_generator.rb +42 -0
  114. data/lib/active_record/encryption/key_provider.rb +46 -0
  115. data/lib/active_record/encryption/message.rb +33 -0
  116. data/lib/active_record/encryption/message_serializer.rb +80 -0
  117. data/lib/active_record/encryption/null_encryptor.rb +21 -0
  118. data/lib/active_record/encryption/properties.rb +76 -0
  119. data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
  120. data/lib/active_record/encryption/scheme.rb +99 -0
  121. data/lib/active_record/encryption.rb +55 -0
  122. data/lib/active_record/enum.rb +41 -41
  123. data/lib/active_record/errors.rb +66 -3
  124. data/lib/active_record/fixture_set/file.rb +15 -1
  125. data/lib/active_record/fixture_set/table_row.rb +40 -5
  126. data/lib/active_record/fixture_set/table_rows.rb +4 -4
  127. data/lib/active_record/fixtures.rb +16 -11
  128. data/lib/active_record/future_result.rb +139 -0
  129. data/lib/active_record/gem_version.rb +4 -4
  130. data/lib/active_record/inheritance.rb +55 -17
  131. data/lib/active_record/insert_all.rb +34 -5
  132. data/lib/active_record/integration.rb +1 -1
  133. data/lib/active_record/internal_metadata.rb +1 -5
  134. data/lib/active_record/locking/optimistic.rb +10 -9
  135. data/lib/active_record/log_subscriber.rb +6 -2
  136. data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
  137. data/lib/active_record/middleware/database_selector.rb +8 -3
  138. data/lib/active_record/migration/command_recorder.rb +4 -4
  139. data/lib/active_record/migration/compatibility.rb +89 -10
  140. data/lib/active_record/migration/join_table.rb +1 -1
  141. data/lib/active_record/migration.rb +109 -79
  142. data/lib/active_record/model_schema.rb +45 -31
  143. data/lib/active_record/nested_attributes.rb +3 -3
  144. data/lib/active_record/no_touching.rb +2 -2
  145. data/lib/active_record/null_relation.rb +2 -6
  146. data/lib/active_record/persistence.rb +134 -45
  147. data/lib/active_record/query_cache.rb +2 -2
  148. data/lib/active_record/query_logs.rb +203 -0
  149. data/lib/active_record/querying.rb +15 -5
  150. data/lib/active_record/railtie.rb +117 -17
  151. data/lib/active_record/railties/controller_runtime.rb +1 -1
  152. data/lib/active_record/railties/databases.rake +72 -48
  153. data/lib/active_record/readonly_attributes.rb +11 -0
  154. data/lib/active_record/reflection.rb +45 -44
  155. data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
  156. data/lib/active_record/relation/batches.rb +3 -3
  157. data/lib/active_record/relation/calculations.rb +39 -26
  158. data/lib/active_record/relation/delegation.rb +6 -6
  159. data/lib/active_record/relation/finder_methods.rb +31 -22
  160. data/lib/active_record/relation/merger.rb +20 -13
  161. data/lib/active_record/relation/predicate_builder.rb +1 -6
  162. data/lib/active_record/relation/query_attribute.rb +5 -11
  163. data/lib/active_record/relation/query_methods.rb +230 -47
  164. data/lib/active_record/relation/record_fetch_warning.rb +2 -2
  165. data/lib/active_record/relation/spawn_methods.rb +2 -2
  166. data/lib/active_record/relation/where_clause.rb +8 -4
  167. data/lib/active_record/relation.rb +166 -77
  168. data/lib/active_record/result.rb +17 -2
  169. data/lib/active_record/runtime_registry.rb +2 -4
  170. data/lib/active_record/sanitization.rb +11 -7
  171. data/lib/active_record/schema_dumper.rb +3 -3
  172. data/lib/active_record/schema_migration.rb +0 -4
  173. data/lib/active_record/scoping/default.rb +61 -12
  174. data/lib/active_record/scoping/named.rb +3 -11
  175. data/lib/active_record/scoping.rb +40 -22
  176. data/lib/active_record/serialization.rb +1 -1
  177. data/lib/active_record/signed_id.rb +1 -1
  178. data/lib/active_record/tasks/database_tasks.rb +106 -22
  179. data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
  180. data/lib/active_record/tasks/postgresql_database_tasks.rb +14 -11
  181. data/lib/active_record/test_databases.rb +1 -1
  182. data/lib/active_record/test_fixtures.rb +4 -4
  183. data/lib/active_record/timestamp.rb +3 -4
  184. data/lib/active_record/transactions.rb +9 -14
  185. data/lib/active_record/translation.rb +2 -2
  186. data/lib/active_record/type/adapter_specific_registry.rb +32 -7
  187. data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
  188. data/lib/active_record/type/internal/timezone.rb +2 -2
  189. data/lib/active_record/type/serialized.rb +1 -1
  190. data/lib/active_record/type/type_map.rb +17 -20
  191. data/lib/active_record/type.rb +1 -2
  192. data/lib/active_record/validations/associated.rb +1 -1
  193. data/lib/active_record.rb +170 -2
  194. data/lib/arel/attributes/attribute.rb +0 -8
  195. data/lib/arel/crud.rb +18 -22
  196. data/lib/arel/delete_manager.rb +2 -4
  197. data/lib/arel/insert_manager.rb +2 -3
  198. data/lib/arel/nodes/casted.rb +1 -1
  199. data/lib/arel/nodes/delete_statement.rb +8 -13
  200. data/lib/arel/nodes/insert_statement.rb +2 -2
  201. data/lib/arel/nodes/select_core.rb +2 -2
  202. data/lib/arel/nodes/select_statement.rb +2 -2
  203. data/lib/arel/nodes/update_statement.rb +3 -2
  204. data/lib/arel/predications.rb +1 -1
  205. data/lib/arel/select_manager.rb +10 -4
  206. data/lib/arel/table.rb +0 -1
  207. data/lib/arel/tree_manager.rb +0 -12
  208. data/lib/arel/update_manager.rb +2 -4
  209. data/lib/arel/visitors/dot.rb +80 -90
  210. data/lib/arel/visitors/mysql.rb +6 -1
  211. data/lib/arel/visitors/postgresql.rb +0 -10
  212. data/lib/arel/visitors/to_sql.rb +43 -2
  213. data/lib/arel.rb +1 -1
  214. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  215. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
  216. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  217. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  218. metadata +55 -17
@@ -193,8 +193,8 @@ module ActiveRecord
193
193
  # need to share a connection pool so that the reading connection
194
194
  # can see data in the open transaction on the writing connection.
195
195
  def setup_shared_connection_pool
196
- if ActiveRecord::Base.legacy_connection_handling
197
- writing_handler = ActiveRecord::Base.connection_handlers[ActiveRecord::Base.writing_role]
196
+ if ActiveRecord.legacy_connection_handling
197
+ writing_handler = ActiveRecord::Base.connection_handlers[ActiveRecord.writing_role]
198
198
 
199
199
  ActiveRecord::Base.connection_handlers.values.each do |handler|
200
200
  if handler != writing_handler
@@ -221,7 +221,7 @@ module ActiveRecord
221
221
  handler.connection_pool_names.each do |name|
222
222
  pool_manager = handler.send(:owner_to_pool_manager)[name]
223
223
  pool_manager.shard_names.each do |shard_name|
224
- writing_pool_config = pool_manager.get_pool_config(ActiveRecord::Base.writing_role, shard_name)
224
+ writing_pool_config = pool_manager.get_pool_config(ActiveRecord.writing_role, shard_name)
225
225
  @saved_pool_configs[name][shard_name] ||= {}
226
226
  pool_manager.role_names.each do |role|
227
227
  next unless pool_config = pool_manager.get_pool_config(role, shard_name)
@@ -236,7 +236,7 @@ module ActiveRecord
236
236
  end
237
237
 
238
238
  def teardown_shared_connection_pool
239
- if ActiveRecord::Base.legacy_connection_handling
239
+ if ActiveRecord.legacy_connection_handling
240
240
  @legacy_saved_pool_configs.each_pair do |handler, names|
241
241
  names.each_pair do |name, shards|
242
242
  shards.each_pair do |shard_name, pool_config|
@@ -75,7 +75,7 @@ module ActiveRecord
75
75
  end
76
76
 
77
77
  def current_time_from_proper_timezone
78
- default_timezone == :utc ? Time.now.utc : Time.now
78
+ ActiveRecord.default_timezone == :utc ? Time.now.utc : Time.now
79
79
  end
80
80
 
81
81
  private
@@ -127,7 +127,7 @@ module ActiveRecord
127
127
  end
128
128
 
129
129
  def should_record_timestamps?
130
- record_timestamps && (!partial_writes? || has_changes_to_save?)
130
+ record_timestamps && (!partial_updates? || has_changes_to_save?)
131
131
  end
132
132
 
133
133
  def timestamp_attributes_for_create_in_model
@@ -148,8 +148,7 @@ module ActiveRecord
148
148
 
149
149
  def max_updated_column_timestamp
150
150
  timestamp_attributes_for_update_in_model
151
- .map { |attr| self[attr]&.to_time }
152
- .compact
151
+ .filter_map { |attr| self[attr]&.to_time }
153
152
  .max
154
153
  end
155
154
 
@@ -4,7 +4,7 @@ module ActiveRecord
4
4
  # See ActiveRecord::Transactions::ClassMethods for documentation.
5
5
  module Transactions
6
6
  extend ActiveSupport::Concern
7
- #:nodoc:
7
+ # :nodoc:
8
8
  ACTIONS = [:create, :destroy, :update]
9
9
 
10
10
  included do
@@ -290,19 +290,19 @@ module ActiveRecord
290
290
  self.class.transaction(**options, &block)
291
291
  end
292
292
 
293
- def destroy #:nodoc:
293
+ def destroy # :nodoc:
294
294
  with_transaction_returning_status { super }
295
295
  end
296
296
 
297
- def save(**) #:nodoc:
297
+ def save(**) # :nodoc:
298
298
  with_transaction_returning_status { super }
299
299
  end
300
300
 
301
- def save!(**) #:nodoc:
301
+ def save!(**) # :nodoc:
302
302
  with_transaction_returning_status { super }
303
303
  end
304
304
 
305
- def touch(*, **) #:nodoc:
305
+ def touch(*, **) # :nodoc:
306
306
  with_transaction_returning_status { super }
307
307
  end
308
308
 
@@ -314,8 +314,8 @@ module ActiveRecord
314
314
  #
315
315
  # Ensure that it is not called if the object was never persisted (failed create),
316
316
  # but call it after the commit of a destroyed object.
317
- def committed!(should_run_callbacks: true) #:nodoc:
318
- force_clear_transaction_record_state
317
+ def committed!(should_run_callbacks: true) # :nodoc:
318
+ @_start_transaction_state = nil
319
319
  if should_run_callbacks
320
320
  @_committed_already_called = true
321
321
  _run_commit_callbacks
@@ -326,7 +326,7 @@ module ActiveRecord
326
326
 
327
327
  # Call the #after_rollback callbacks. The +force_restore_state+ argument indicates if the record
328
328
  # state should be rolled back to the beginning or just to the last savepoint.
329
- def rolledback!(force_restore_state: false, should_run_callbacks: true) #:nodoc:
329
+ def rolledback!(force_restore_state: false, should_run_callbacks: true) # :nodoc:
330
330
  if should_run_callbacks
331
331
  _run_rollback_callbacks
332
332
  end
@@ -389,12 +389,7 @@ module ActiveRecord
389
389
  def clear_transaction_record_state
390
390
  return unless @_start_transaction_state
391
391
  @_start_transaction_state[:level] -= 1
392
- force_clear_transaction_record_state if @_start_transaction_state[:level] < 1
393
- end
394
-
395
- # Force to clear the transaction record state.
396
- def force_clear_transaction_record_state
397
- @_start_transaction_state = nil
392
+ @_start_transaction_state = nil if @_start_transaction_state[:level] < 1
398
393
  end
399
394
 
400
395
  # Restore the new record state and id of a record that was previously saved by a call to save_record_state.
@@ -5,7 +5,7 @@ module ActiveRecord
5
5
  include ActiveModel::Translation
6
6
 
7
7
  # Set the lookup ancestors for ActiveModel.
8
- def lookup_ancestors #:nodoc:
8
+ def lookup_ancestors # :nodoc:
9
9
  klass = self
10
10
  classes = [klass]
11
11
  return classes if klass == ActiveRecord::Base
@@ -17,7 +17,7 @@ module ActiveRecord
17
17
  end
18
18
 
19
19
  # Set the i18n scope to overwrite ActiveModel.
20
- def i18n_scope #:nodoc:
20
+ def i18n_scope # :nodoc:
21
21
  :activerecord
22
22
  end
23
23
  end
@@ -5,15 +5,40 @@ require "active_model/type/registry"
5
5
  module ActiveRecord
6
6
  # :stopdoc:
7
7
  module Type
8
- class AdapterSpecificRegistry < ActiveModel::Type::Registry
8
+ class AdapterSpecificRegistry # :nodoc:
9
+ def initialize
10
+ @registrations = []
11
+ end
12
+
13
+ def initialize_copy(other)
14
+ @registrations = @registrations.dup
15
+ super
16
+ end
17
+
9
18
  def add_modifier(options, klass, **args)
10
19
  registrations << DecorationRegistration.new(options, klass, **args)
11
20
  end
12
21
 
13
- private
14
- def registration_klass
15
- Registration
22
+ def register(type_name, klass = nil, **options, &block)
23
+ unless block_given?
24
+ block = proc { |_, *args| klass.new(*args) }
25
+ block.ruby2_keywords if block.respond_to?(:ruby2_keywords)
16
26
  end
27
+ registrations << Registration.new(type_name, block, **options)
28
+ end
29
+
30
+ def lookup(symbol, *args, **kwargs)
31
+ registration = find_registration(symbol, *args, **kwargs)
32
+
33
+ if registration
34
+ registration.call(self, symbol, *args, **kwargs)
35
+ else
36
+ raise ArgumentError, "Unknown type #{symbol.inspect}"
37
+ end
38
+ end
39
+
40
+ private
41
+ attr_reader :registrations
17
42
 
18
43
  def find_registration(symbol, *args, **kwargs)
19
44
  registrations
@@ -22,7 +47,7 @@ module ActiveRecord
22
47
  end
23
48
  end
24
49
 
25
- class Registration
50
+ class Registration # :nodoc:
26
51
  def initialize(name, block, adapter: nil, override: nil)
27
52
  @name = name
28
53
  @block = block
@@ -89,7 +114,7 @@ module ActiveRecord
89
114
  end
90
115
  end
91
116
 
92
- class DecorationRegistration < Registration
117
+ class DecorationRegistration < Registration # :nodoc:
93
118
  def initialize(options, klass, adapter: nil)
94
119
  @options = options
95
120
  @klass = klass
@@ -120,7 +145,7 @@ module ActiveRecord
120
145
  end
121
146
  end
122
147
 
123
- class TypeConflictError < StandardError
148
+ class TypeConflictError < StandardError # :nodoc:
124
149
  end
125
150
  # :startdoc:
126
151
  end
@@ -2,7 +2,40 @@
2
2
 
3
3
  module ActiveRecord
4
4
  module Type
5
- class HashLookupTypeMap < TypeMap # :nodoc:
5
+ class HashLookupTypeMap # :nodoc:
6
+ def initialize(parent = nil)
7
+ @mapping = {}
8
+ @cache = Concurrent::Map.new do |h, key|
9
+ h.fetch_or_store(key, Concurrent::Map.new)
10
+ end
11
+ end
12
+
13
+ def lookup(lookup_key, *args)
14
+ fetch(lookup_key, *args) { Type.default_value }
15
+ end
16
+
17
+ def fetch(lookup_key, *args, &block)
18
+ @cache[lookup_key].fetch_or_store(args) do
19
+ perform_fetch(lookup_key, *args, &block)
20
+ end
21
+ end
22
+
23
+ def register_type(key, value = nil, &block)
24
+ raise ::ArgumentError unless value || block
25
+
26
+ if block
27
+ @mapping[key] = block
28
+ else
29
+ @mapping[key] = proc { value }
30
+ end
31
+ @cache.clear
32
+ end
33
+
34
+ def clear
35
+ @mapping.clear
36
+ @cache.clear
37
+ end
38
+
6
39
  def alias_type(type, alias_type)
7
40
  register_type(type) { |_, *args| lookup(alias_type, *args) }
8
41
  end
@@ -5,11 +5,11 @@ module ActiveRecord
5
5
  module Internal
6
6
  module Timezone
7
7
  def is_utc?
8
- ActiveRecord::Base.default_timezone == :utc
8
+ ActiveRecord.default_timezone == :utc
9
9
  end
10
10
 
11
11
  def default_timezone
12
- ActiveRecord::Base.default_timezone
12
+ ActiveRecord.default_timezone
13
13
  end
14
14
  end
15
15
  end
@@ -31,7 +31,7 @@ module ActiveRecord
31
31
  end
32
32
 
33
33
  def inspect
34
- Kernel.instance_method(:inspect).bind(self).call
34
+ Kernel.instance_method(:inspect).bind_call(self)
35
35
  end
36
36
 
37
37
  def changed_in_place?(raw_old_value, value)
@@ -5,55 +5,52 @@ require "concurrent/map"
5
5
  module ActiveRecord
6
6
  module Type
7
7
  class TypeMap # :nodoc:
8
- def initialize
8
+ def initialize(parent = nil)
9
9
  @mapping = {}
10
- @cache = Concurrent::Map.new do |h, key|
11
- h.fetch_or_store(key, Concurrent::Map.new)
12
- end
10
+ @parent = parent
11
+ @cache = Concurrent::Map.new
13
12
  end
14
13
 
15
- def lookup(lookup_key, *args)
16
- fetch(lookup_key, *args) { Type.default_value }
14
+ def lookup(lookup_key)
15
+ fetch(lookup_key) { Type.default_value }
17
16
  end
18
17
 
19
- def fetch(lookup_key, *args, &block)
20
- @cache[lookup_key].fetch_or_store(args) do
21
- perform_fetch(lookup_key, *args, &block)
18
+ def fetch(lookup_key, &block)
19
+ @cache.fetch_or_store(lookup_key) do
20
+ perform_fetch(lookup_key, &block)
22
21
  end
23
22
  end
24
23
 
25
24
  def register_type(key, value = nil, &block)
26
25
  raise ::ArgumentError unless value || block
27
- @cache.clear
28
26
 
29
27
  if block
30
28
  @mapping[key] = block
31
29
  else
32
30
  @mapping[key] = proc { value }
33
31
  end
32
+ @cache.clear
34
33
  end
35
34
 
36
35
  def alias_type(key, target_key)
37
- register_type(key) do |sql_type, *args|
36
+ register_type(key) do |sql_type|
38
37
  metadata = sql_type[/\(.*\)/, 0]
39
- lookup("#{target_key}#{metadata}", *args)
38
+ lookup("#{target_key}#{metadata}")
40
39
  end
41
40
  end
42
41
 
43
- def clear
44
- @mapping.clear
45
- end
46
-
47
- private
48
- def perform_fetch(lookup_key, *args)
42
+ protected
43
+ def perform_fetch(lookup_key, &block)
49
44
  matching_pair = @mapping.reverse_each.detect do |key, _|
50
45
  key === lookup_key
51
46
  end
52
47
 
53
48
  if matching_pair
54
- matching_pair.last.call(lookup_key, *args)
49
+ matching_pair.last.call(lookup_key)
50
+ elsif @parent
51
+ @parent.perform_fetch(lookup_key, &block)
55
52
  else
56
- yield lookup_key, *args
53
+ yield lookup_key
57
54
  end
58
55
  end
59
56
  end
@@ -47,8 +47,7 @@ module ActiveRecord
47
47
  end
48
48
 
49
49
  def adapter_name_from(model) # :nodoc:
50
- # TODO: this shouldn't depend on a connection to the database
51
- model.connection.adapter_name.downcase.to_sym
50
+ model.connection_db_config.adapter.to_sym
52
51
  end
53
52
 
54
53
  private
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ActiveRecord
4
4
  module Validations
5
- class AssociatedValidator < ActiveModel::EachValidator #:nodoc:
5
+ class AssociatedValidator < ActiveModel::EachValidator # :nodoc:
6
6
  def validate_each(record, attribute, value)
7
7
  if Array(value).reject { |r| valid_object?(r) }.any?
8
8
  record.errors.add(attribute, :invalid, **options.merge(value: value))
data/lib/active_record.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # Copyright (c) 2004-2022 David Heinemeier Hansson
4
+ # Copyright (c) 2004-2021 David Heinemeier Hansson
5
5
  #
6
6
  # Permission is hereby granted, free of charge, to any person obtaining
7
7
  # a copy of this software and associated documentation files (the
@@ -43,6 +43,7 @@ module ActiveRecord
43
43
  autoload :CounterCache
44
44
  autoload :DynamicMatchers
45
45
  autoload :DelegatedType
46
+ autoload :Encryption
46
47
  autoload :Enum
47
48
  autoload :InternalMetadata
48
49
  autoload :Explain
@@ -57,6 +58,7 @@ module ActiveRecord
57
58
  autoload :Persistence
58
59
  autoload :QueryCache
59
60
  autoload :Querying
61
+ autoload :QueryLogs
60
62
  autoload :ReadonlyAttributes
61
63
  autoload :RecordInvalid, "active_record/validations"
62
64
  autoload :Reflection
@@ -67,7 +69,6 @@ module ActiveRecord
67
69
  autoload :SchemaMigration
68
70
  autoload :Scoping
69
71
  autoload :Serialization
70
- autoload :StatementCache
71
72
  autoload :Store
72
73
  autoload :SignedId
73
74
  autoload :Suppressor
@@ -79,6 +80,7 @@ module ActiveRecord
79
80
  autoload :DestroyAssociationAsyncJob
80
81
 
81
82
  eager_autoload do
83
+ autoload :StatementCache
82
84
  autoload :ConnectionAdapters
83
85
 
84
86
  autoload :Aggregations
@@ -86,11 +88,13 @@ module ActiveRecord
86
88
  autoload :AttributeAssignment
87
89
  autoload :AttributeMethods
88
90
  autoload :AutosaveAssociation
91
+ autoload :AsynchronousQueriesTracker
89
92
 
90
93
  autoload :LegacyYamlAdapter
91
94
 
92
95
  autoload :Relation
93
96
  autoload :AssociationRelation
97
+ autoload :DisableJoinsAssociationRelation
94
98
  autoload :NullRelation
95
99
 
96
100
  autoload_under "relation" do
@@ -104,6 +108,7 @@ module ActiveRecord
104
108
  end
105
109
 
106
110
  autoload :Result
111
+ autoload :FutureResult
107
112
  autoload :TableMetadata
108
113
  autoload :Type
109
114
  end
@@ -165,6 +170,168 @@ module ActiveRecord
165
170
  autoload :TestDatabases, "active_record/test_databases"
166
171
  autoload :TestFixtures, "active_record/fixtures"
167
172
 
173
+ # A list of tables or regex's to match tables to ignore when
174
+ # dumping the schema cache. For example if this is set to +[/^_/]+
175
+ # the schema cache will not dump tables named with an underscore.
176
+ singleton_class.attr_accessor :schema_cache_ignored_tables
177
+ self.schema_cache_ignored_tables = []
178
+
179
+ singleton_class.attr_accessor :legacy_connection_handling
180
+ self.legacy_connection_handling = true
181
+
182
+ ##
183
+ # :singleton-method:
184
+ # Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
185
+ # dates and times from the database. This is set to :utc by default.
186
+ singleton_class.attr_accessor :default_timezone
187
+ self.default_timezone = :utc
188
+
189
+ singleton_class.attr_accessor :writing_role
190
+ self.writing_role = :writing
191
+
192
+ singleton_class.attr_accessor :reading_role
193
+ self.reading_role = :reading
194
+
195
+ # Sets the async_query_executor for an application. By default the thread pool executor
196
+ # set to +nil+ which will not run queries in the background. Applications must configure
197
+ # a thread pool executor to use this feature. Options are:
198
+ #
199
+ # * nil - Does not initialize a thread pool executor. Any async calls will be
200
+ # run in the foreground.
201
+ # * :global_thread_pool - Initializes a single +Concurrent::ThreadPoolExecutor+
202
+ # that uses the +async_query_concurrency+ for the +max_threads+ value.
203
+ # * :multi_thread_pool - Initializes a +Concurrent::ThreadPoolExecutor+ for each
204
+ # database connection. The initializer values are defined in the configuration hash.
205
+ singleton_class.attr_accessor :async_query_executor
206
+ self.async_query_executor = nil
207
+
208
+ def self.global_thread_pool_async_query_executor # :nodoc:
209
+ concurrency = global_executor_concurrency || 4
210
+ @global_thread_pool_async_query_executor ||= Concurrent::ThreadPoolExecutor.new(
211
+ min_threads: 0,
212
+ max_threads: concurrency,
213
+ max_queue: concurrency * 4,
214
+ fallback_policy: :caller_runs
215
+ )
216
+ end
217
+
218
+ # Set the +global_executor_concurrency+. This configuration value can only be used
219
+ # with the global thread pool async query executor.
220
+ def self.global_executor_concurrency=(global_executor_concurrency)
221
+ if self.async_query_executor.nil? || self.async_query_executor == :multi_thread_pool
222
+ 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."
223
+ end
224
+
225
+ @global_executor_concurrency = global_executor_concurrency
226
+ end
227
+
228
+ def self.global_executor_concurrency # :nodoc:
229
+ @global_executor_concurrency ||= nil
230
+ end
231
+
232
+ singleton_class.attr_accessor :index_nested_attribute_errors
233
+ self.index_nested_attribute_errors = false
234
+
235
+ ##
236
+ # :singleton-method:
237
+ #
238
+ # Specifies if the methods calling database queries should be logged below
239
+ # their relevant queries. Defaults to false.
240
+ singleton_class.attr_accessor :verbose_query_logs
241
+ self.verbose_query_logs = false
242
+
243
+ ##
244
+ # :singleton-method:
245
+ #
246
+ # Specifies the names of the queues used by background jobs.
247
+ singleton_class.attr_accessor :queues
248
+ self.queues = {}
249
+
250
+ singleton_class.attr_accessor :maintain_test_schema
251
+ self.maintain_test_schema = nil
252
+
253
+ ##
254
+ # :singleton-method:
255
+ # Specify a threshold for the size of query result sets. If the number of
256
+ # records in the set exceeds the threshold, a warning is logged. This can
257
+ # be used to identify queries which load thousands of records and
258
+ # potentially cause memory bloat.
259
+ singleton_class.attr_accessor :warn_on_records_fetched_greater_than
260
+ self.warn_on_records_fetched_greater_than = false
261
+
262
+ singleton_class.attr_accessor :application_record_class
263
+ self.application_record_class = nil
264
+
265
+ ##
266
+ # :singleton-method:
267
+ # Set the application to log or raise when an association violates strict loading.
268
+ # Defaults to :raise.
269
+ singleton_class.attr_accessor :action_on_strict_loading_violation
270
+ self.action_on_strict_loading_violation = :raise
271
+
272
+ ##
273
+ # :singleton-method:
274
+ # Specifies the format to use when dumping the database schema with Rails'
275
+ # Rakefile. If :sql, the schema is dumped as (potentially database-
276
+ # specific) SQL statements. If :ruby, the schema is dumped as an
277
+ # ActiveRecord::Schema file which can be loaded into any database that
278
+ # supports migrations. Use :ruby if you want to have different database
279
+ # adapters for, e.g., your development and test environments.
280
+ singleton_class.attr_accessor :schema_format
281
+ self.schema_format = :ruby
282
+
283
+ ##
284
+ # :singleton-method:
285
+ # Specifies if an error should be raised if the query has an order being
286
+ # ignored when doing batch queries. Useful in applications where the
287
+ # scope being ignored is error-worthy, rather than a warning.
288
+ singleton_class.attr_accessor :error_on_ignored_order
289
+ self.error_on_ignored_order = false
290
+
291
+ ##
292
+ # :singleton-method:
293
+ # Specify whether or not to use timestamps for migration versions
294
+ singleton_class.attr_accessor :timestamped_migrations
295
+ self.timestamped_migrations = true
296
+
297
+ ##
298
+ # :singleton-method:
299
+ # Specify whether schema dump should happen at the end of the
300
+ # bin/rails db:migrate command. This is true by default, which is useful for the
301
+ # development environment. This should ideally be false in the production
302
+ # environment where dumping schema is rarely needed.
303
+ singleton_class.attr_accessor :dump_schema_after_migration
304
+ self.dump_schema_after_migration = true
305
+
306
+ ##
307
+ # :singleton-method:
308
+ # Specifies which database schemas to dump when calling db:schema:dump.
309
+ # If the value is :schema_search_path (the default), any schemas listed in
310
+ # schema_search_path are dumped. Use :all to dump all schemas regardless
311
+ # of schema_search_path, or a string of comma separated schemas for a
312
+ # custom list.
313
+ singleton_class.attr_accessor :dump_schemas
314
+ self.dump_schemas = :schema_search_path
315
+
316
+ ##
317
+ # :singleton-method:
318
+ # Show a warning when Rails couldn't parse your database.yml
319
+ # for multiple databases.
320
+ singleton_class.attr_accessor :suppress_multiple_database_warning
321
+ self.suppress_multiple_database_warning = false
322
+
323
+ ##
324
+ # :singleton-method:
325
+ # If true, Rails will verify all foreign keys in the database after loading fixtures.
326
+ # An error will be raised if there are any foreign key violations, indicating incorrectly
327
+ # written fixtures.
328
+ # Supported by PostgreSQL and SQLite.
329
+ singleton_class.attr_accessor :verify_foreign_keys_for_fixtures
330
+ self.verify_foreign_keys_for_fixtures = false
331
+
332
+ singleton_class.attr_accessor :query_transformers
333
+ self.query_transformers = []
334
+
168
335
  def self.eager_load!
169
336
  super
170
337
  ActiveRecord::Locking.eager_load!
@@ -172,6 +339,7 @@ module ActiveRecord
172
339
  ActiveRecord::Associations.eager_load!
173
340
  ActiveRecord::AttributeMethods.eager_load!
174
341
  ActiveRecord::ConnectionAdapters.eager_load!
342
+ ActiveRecord::Encryption.eager_load!
175
343
  end
176
344
  end
177
345
 
@@ -27,14 +27,6 @@ module Arel # :nodoc: all
27
27
  relation.able_to_type_cast?
28
28
  end
29
29
  end
30
-
31
- class String < Attribute; end
32
- class Time < Attribute; end
33
- class Boolean < Attribute; end
34
- class Decimal < Attribute; end
35
- class Float < Attribute; end
36
- class Integer < Attribute; end
37
- class Undefined < Attribute; end
38
30
  end
39
31
 
40
32
  Attribute = Attributes::Attribute
data/lib/arel/crud.rb CHANGED
@@ -4,23 +4,6 @@ module Arel # :nodoc: all
4
4
  ###
5
5
  # FIXME hopefully we can remove this
6
6
  module Crud
7
- def compile_update(values, pk)
8
- um = UpdateManager.new
9
-
10
- if Nodes::SqlLiteral === values
11
- relation = @ctx.from
12
- else
13
- relation = values.first.first.relation
14
- end
15
- um.key = pk
16
- um.table relation
17
- um.set values
18
- um.take @ast.limit.expr if @ast.limit
19
- um.order(*@ast.orders)
20
- um.wheres = @ctx.wheres
21
- um
22
- end
23
-
24
7
  def compile_insert(values)
25
8
  im = create_insert
26
9
  im.insert values
@@ -31,11 +14,24 @@ module Arel # :nodoc: all
31
14
  InsertManager.new
32
15
  end
33
16
 
34
- def compile_delete
35
- dm = DeleteManager.new
36
- dm.take @ast.limit.expr if @ast.limit
37
- dm.wheres = @ctx.wheres
38
- dm.from @ctx.froms
17
+ def compile_update(values, key = nil)
18
+ um = UpdateManager.new(source)
19
+ um.set(values)
20
+ um.take(limit)
21
+ um.offset(offset)
22
+ um.order(*orders)
23
+ um.wheres = constraints
24
+ um.key = key
25
+ um
26
+ end
27
+
28
+ def compile_delete(key = nil)
29
+ dm = DeleteManager.new(source)
30
+ dm.take(limit)
31
+ dm.offset(offset)
32
+ dm.order(*orders)
33
+ dm.wheres = constraints
34
+ dm.key = key
39
35
  dm
40
36
  end
41
37
  end