activerecord 6.1.7.4 → 7.0.6

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.
Files changed (249) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1449 -1014
  3. data/README.rdoc +3 -3
  4. data/lib/active_record/aggregations.rb +1 -1
  5. data/lib/active_record/association_relation.rb +0 -10
  6. data/lib/active_record/associations/association.rb +33 -17
  7. data/lib/active_record/associations/association_scope.rb +1 -3
  8. data/lib/active_record/associations/belongs_to_association.rb +15 -4
  9. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
  10. data/lib/active_record/associations/builder/association.rb +8 -2
  11. data/lib/active_record/associations/builder/belongs_to.rb +19 -6
  12. data/lib/active_record/associations/builder/collection_association.rb +10 -3
  13. data/lib/active_record/associations/builder/has_many.rb +3 -2
  14. data/lib/active_record/associations/builder/has_one.rb +2 -1
  15. data/lib/active_record/associations/builder/singular_association.rb +2 -2
  16. data/lib/active_record/associations/collection_association.rb +19 -21
  17. data/lib/active_record/associations/collection_proxy.rb +10 -5
  18. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  19. data/lib/active_record/associations/has_many_association.rb +8 -5
  20. data/lib/active_record/associations/has_many_through_association.rb +2 -1
  21. data/lib/active_record/associations/has_one_association.rb +14 -7
  22. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  23. data/lib/active_record/associations/join_dependency.rb +23 -15
  24. data/lib/active_record/associations/preloader/association.rb +186 -52
  25. data/lib/active_record/associations/preloader/batch.rb +48 -0
  26. data/lib/active_record/associations/preloader/branch.rb +147 -0
  27. data/lib/active_record/associations/preloader/through_association.rb +50 -14
  28. data/lib/active_record/associations/preloader.rb +39 -113
  29. data/lib/active_record/associations/singular_association.rb +15 -7
  30. data/lib/active_record/associations/through_association.rb +3 -3
  31. data/lib/active_record/associations.rb +138 -100
  32. data/lib/active_record/asynchronous_queries_tracker.rb +60 -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 +49 -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 +8 -6
  39. data/lib/active_record/attribute_methods/serialization.rb +57 -19
  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 +19 -22
  43. data/lib/active_record/attributes.rb +24 -35
  44. data/lib/active_record/autosave_association.rb +17 -28
  45. data/lib/active_record/base.rb +19 -1
  46. data/lib/active_record/callbacks.rb +14 -16
  47. data/lib/active_record/coders/yaml_column.rb +4 -8
  48. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -0
  49. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
  50. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
  51. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +47 -561
  52. data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -17
  53. data/lib/active_record/connection_adapters/abstract/database_statements.rb +46 -22
  54. data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
  55. data/lib/active_record/connection_adapters/abstract/quoting.rb +42 -72
  56. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
  57. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +52 -23
  58. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
  59. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +82 -25
  60. data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -22
  61. data/lib/active_record/connection_adapters/abstract_adapter.rb +153 -74
  62. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +112 -84
  63. data/lib/active_record/connection_adapters/column.rb +4 -0
  64. data/lib/active_record/connection_adapters/mysql/database_statements.rb +36 -24
  65. data/lib/active_record/connection_adapters/mysql/quoting.rb +45 -21
  66. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +4 -1
  67. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +7 -1
  68. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +20 -1
  69. data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -6
  70. data/lib/active_record/connection_adapters/pool_config.rb +7 -7
  71. data/lib/active_record/connection_adapters/postgresql/column.rb +19 -1
  72. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +20 -17
  73. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  74. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
  75. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
  76. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
  77. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
  78. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  79. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  80. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  81. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  82. data/lib/active_record/connection_adapters/postgresql/quoting.rb +71 -71
  83. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +34 -0
  84. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +21 -1
  85. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +22 -1
  86. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -0
  87. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +40 -21
  88. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
  89. data/lib/active_record/connection_adapters/postgresql_adapter.rb +207 -106
  90. data/lib/active_record/connection_adapters/schema_cache.rb +39 -38
  91. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +25 -19
  92. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +28 -16
  93. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +17 -15
  94. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +97 -32
  95. data/lib/active_record/connection_adapters.rb +6 -5
  96. data/lib/active_record/connection_handling.rb +49 -55
  97. data/lib/active_record/core.rb +123 -148
  98. data/lib/active_record/database_configurations/connection_url_resolver.rb +2 -1
  99. data/lib/active_record/database_configurations/database_config.rb +12 -9
  100. data/lib/active_record/database_configurations/hash_config.rb +63 -5
  101. data/lib/active_record/database_configurations/url_config.rb +2 -2
  102. data/lib/active_record/database_configurations.rb +15 -32
  103. data/lib/active_record/delegated_type.rb +53 -12
  104. data/lib/active_record/destroy_association_async_job.rb +1 -1
  105. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  106. data/lib/active_record/dynamic_matchers.rb +1 -1
  107. data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
  108. data/lib/active_record/encryption/cipher.rb +53 -0
  109. data/lib/active_record/encryption/config.rb +44 -0
  110. data/lib/active_record/encryption/configurable.rb +67 -0
  111. data/lib/active_record/encryption/context.rb +35 -0
  112. data/lib/active_record/encryption/contexts.rb +72 -0
  113. data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
  114. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  115. data/lib/active_record/encryption/encryptable_record.rb +206 -0
  116. data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
  117. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  118. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  119. data/lib/active_record/encryption/encryptor.rb +155 -0
  120. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  121. data/lib/active_record/encryption/errors.rb +15 -0
  122. data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
  123. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  124. data/lib/active_record/encryption/key.rb +28 -0
  125. data/lib/active_record/encryption/key_generator.rb +42 -0
  126. data/lib/active_record/encryption/key_provider.rb +46 -0
  127. data/lib/active_record/encryption/message.rb +33 -0
  128. data/lib/active_record/encryption/message_serializer.rb +90 -0
  129. data/lib/active_record/encryption/null_encryptor.rb +21 -0
  130. data/lib/active_record/encryption/properties.rb +76 -0
  131. data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
  132. data/lib/active_record/encryption/scheme.rb +99 -0
  133. data/lib/active_record/encryption.rb +55 -0
  134. data/lib/active_record/enum.rb +50 -43
  135. data/lib/active_record/errors.rb +67 -4
  136. data/lib/active_record/explain_registry.rb +11 -6
  137. data/lib/active_record/explain_subscriber.rb +1 -1
  138. data/lib/active_record/fixture_set/file.rb +15 -1
  139. data/lib/active_record/fixture_set/table_row.rb +41 -6
  140. data/lib/active_record/fixture_set/table_rows.rb +4 -4
  141. data/lib/active_record/fixtures.rb +20 -23
  142. data/lib/active_record/future_result.rb +139 -0
  143. data/lib/active_record/gem_version.rb +5 -5
  144. data/lib/active_record/inheritance.rb +55 -17
  145. data/lib/active_record/insert_all.rb +80 -14
  146. data/lib/active_record/integration.rb +4 -3
  147. data/lib/active_record/internal_metadata.rb +1 -5
  148. data/lib/active_record/legacy_yaml_adapter.rb +2 -39
  149. data/lib/active_record/locking/optimistic.rb +36 -21
  150. data/lib/active_record/locking/pessimistic.rb +10 -4
  151. data/lib/active_record/log_subscriber.rb +23 -7
  152. data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
  153. data/lib/active_record/middleware/database_selector.rb +18 -6
  154. data/lib/active_record/middleware/shard_selector.rb +60 -0
  155. data/lib/active_record/migration/command_recorder.rb +8 -9
  156. data/lib/active_record/migration/compatibility.rb +91 -2
  157. data/lib/active_record/migration/join_table.rb +1 -1
  158. data/lib/active_record/migration.rb +115 -84
  159. data/lib/active_record/model_schema.rb +58 -59
  160. data/lib/active_record/nested_attributes.rb +13 -12
  161. data/lib/active_record/no_touching.rb +3 -3
  162. data/lib/active_record/null_relation.rb +2 -6
  163. data/lib/active_record/persistence.rb +228 -60
  164. data/lib/active_record/query_cache.rb +2 -2
  165. data/lib/active_record/query_logs.rb +149 -0
  166. data/lib/active_record/querying.rb +16 -6
  167. data/lib/active_record/railtie.rb +136 -22
  168. data/lib/active_record/railties/controller_runtime.rb +1 -1
  169. data/lib/active_record/railties/databases.rake +78 -136
  170. data/lib/active_record/readonly_attributes.rb +11 -0
  171. data/lib/active_record/reflection.rb +80 -49
  172. data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
  173. data/lib/active_record/relation/batches.rb +6 -6
  174. data/lib/active_record/relation/calculations.rb +92 -60
  175. data/lib/active_record/relation/delegation.rb +7 -7
  176. data/lib/active_record/relation/finder_methods.rb +31 -35
  177. data/lib/active_record/relation/merger.rb +20 -13
  178. data/lib/active_record/relation/predicate_builder/association_query_value.rb +20 -1
  179. data/lib/active_record/relation/predicate_builder.rb +2 -6
  180. data/lib/active_record/relation/query_attribute.rb +5 -11
  181. data/lib/active_record/relation/query_methods.rb +285 -68
  182. data/lib/active_record/relation/record_fetch_warning.rb +7 -9
  183. data/lib/active_record/relation/spawn_methods.rb +2 -2
  184. data/lib/active_record/relation/where_clause.rb +10 -19
  185. data/lib/active_record/relation.rb +189 -88
  186. data/lib/active_record/result.rb +23 -11
  187. data/lib/active_record/runtime_registry.rb +9 -13
  188. data/lib/active_record/sanitization.rb +17 -12
  189. data/lib/active_record/schema.rb +38 -23
  190. data/lib/active_record/schema_dumper.rb +29 -19
  191. data/lib/active_record/schema_migration.rb +4 -4
  192. data/lib/active_record/scoping/default.rb +60 -13
  193. data/lib/active_record/scoping/named.rb +3 -11
  194. data/lib/active_record/scoping.rb +64 -34
  195. data/lib/active_record/serialization.rb +6 -1
  196. data/lib/active_record/signed_id.rb +3 -3
  197. data/lib/active_record/store.rb +2 -2
  198. data/lib/active_record/suppressor.rb +11 -15
  199. data/lib/active_record/table_metadata.rb +5 -1
  200. data/lib/active_record/tasks/database_tasks.rb +127 -60
  201. data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
  202. data/lib/active_record/tasks/postgresql_database_tasks.rb +19 -13
  203. data/lib/active_record/test_databases.rb +1 -1
  204. data/lib/active_record/test_fixtures.rb +9 -6
  205. data/lib/active_record/timestamp.rb +3 -4
  206. data/lib/active_record/transactions.rb +9 -14
  207. data/lib/active_record/translation.rb +3 -3
  208. data/lib/active_record/type/adapter_specific_registry.rb +32 -7
  209. data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
  210. data/lib/active_record/type/internal/timezone.rb +2 -2
  211. data/lib/active_record/type/serialized.rb +5 -5
  212. data/lib/active_record/type/type_map.rb +17 -20
  213. data/lib/active_record/type.rb +1 -2
  214. data/lib/active_record/validations/associated.rb +4 -4
  215. data/lib/active_record/validations/presence.rb +2 -2
  216. data/lib/active_record/validations/uniqueness.rb +4 -4
  217. data/lib/active_record/version.rb +1 -1
  218. data/lib/active_record.rb +225 -27
  219. data/lib/arel/attributes/attribute.rb +0 -8
  220. data/lib/arel/crud.rb +28 -22
  221. data/lib/arel/delete_manager.rb +18 -4
  222. data/lib/arel/filter_predications.rb +9 -0
  223. data/lib/arel/insert_manager.rb +2 -3
  224. data/lib/arel/nodes/casted.rb +1 -1
  225. data/lib/arel/nodes/delete_statement.rb +12 -13
  226. data/lib/arel/nodes/filter.rb +10 -0
  227. data/lib/arel/nodes/function.rb +1 -0
  228. data/lib/arel/nodes/insert_statement.rb +2 -2
  229. data/lib/arel/nodes/select_core.rb +2 -2
  230. data/lib/arel/nodes/select_statement.rb +2 -2
  231. data/lib/arel/nodes/update_statement.rb +8 -3
  232. data/lib/arel/nodes.rb +1 -0
  233. data/lib/arel/predications.rb +11 -3
  234. data/lib/arel/select_manager.rb +10 -4
  235. data/lib/arel/table.rb +0 -1
  236. data/lib/arel/tree_manager.rb +0 -12
  237. data/lib/arel/update_manager.rb +18 -4
  238. data/lib/arel/visitors/dot.rb +80 -90
  239. data/lib/arel/visitors/mysql.rb +8 -2
  240. data/lib/arel/visitors/postgresql.rb +0 -10
  241. data/lib/arel/visitors/to_sql.rb +58 -2
  242. data/lib/arel.rb +2 -1
  243. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  244. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
  245. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  246. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  247. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  248. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  249. metadata +58 -14
@@ -36,7 +36,7 @@ module ActiveRecord
36
36
  include Savepoints
37
37
 
38
38
  SIMPLE_INT = /\A\d+\z/
39
- COMMENT_REGEX = %r{(?:\-\-.*\n)*|/\*(?:[^\*]|\*[^/])*\*/}m
39
+ COMMENT_REGEX = %r{(?:--.*\n)|/\*(?:[^*]|\*[^/])*\*/}m
40
40
 
41
41
  attr_accessor :pool
42
42
  attr_reader :visitor, :owner, :logger, :lock
@@ -68,7 +68,7 @@ module ActiveRecord
68
68
  def self.build_read_query_regexp(*parts) # :nodoc:
69
69
  parts += DEFAULT_READ_QUERY
70
70
  parts = parts.map { |part| /#{part}/i }
71
- /\A(?:[\(\s]|#{COMMENT_REGEX})*#{Regexp.union(*parts)}/
71
+ /\A(?:[(\s]|#{COMMENT_REGEX})*#{Regexp.union(*parts)}/
72
72
  end
73
73
 
74
74
  def self.quoted_column_names # :nodoc:
@@ -88,7 +88,7 @@ module ActiveRecord
88
88
  @logger = logger
89
89
  @config = config
90
90
  @pool = ActiveRecord::ConnectionAdapters::NullPool.new
91
- @idle_since = Concurrent.monotonic_time
91
+ @idle_since = Process.clock_gettime(Process::CLOCK_MONOTONIC)
92
92
  @visitor = arel_visitor
93
93
  @statements = build_statement_pool
94
94
  @lock = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
@@ -102,6 +102,25 @@ module ActiveRecord
102
102
  )
103
103
  end
104
104
 
105
+ EXCEPTION_NEVER = { Exception => :never }.freeze # :nodoc:
106
+ EXCEPTION_IMMEDIATE = { Exception => :immediate }.freeze # :nodoc:
107
+ private_constant :EXCEPTION_NEVER, :EXCEPTION_IMMEDIATE
108
+ def with_instrumenter(instrumenter, &block) # :nodoc:
109
+ Thread.handle_interrupt(EXCEPTION_NEVER) do
110
+ previous_instrumenter = @instrumenter
111
+ @instrumenter = instrumenter
112
+ Thread.handle_interrupt(EXCEPTION_IMMEDIATE, &block)
113
+ ensure
114
+ @instrumenter = previous_instrumenter
115
+ end
116
+ end
117
+
118
+ def check_if_write_query(sql) # :nodoc:
119
+ if preventing_writes? && write_query?(sql)
120
+ raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
121
+ end
122
+ end
123
+
105
124
  def replica?
106
125
  @config[:replica] || false
107
126
  end
@@ -121,10 +140,10 @@ module ActiveRecord
121
140
  # will return true based on +current_preventing_writes+.
122
141
  def preventing_writes?
123
142
  return true if replica?
124
- return ActiveRecord::Base.connection_handler.prevent_writes if ActiveRecord::Base.legacy_connection_handling
125
- return false if connection_klass.nil?
143
+ return ActiveRecord::Base.connection_handler.prevent_writes if ActiveRecord.legacy_connection_handling
144
+ return false if connection_class.nil?
126
145
 
127
- connection_klass.current_preventing_writes
146
+ connection_class.current_preventing_writes
128
147
  end
129
148
 
130
149
  def migrations_paths # :nodoc:
@@ -159,7 +178,7 @@ module ActiveRecord
159
178
  alias :prepared_statements :prepared_statements?
160
179
 
161
180
  def prepared_statements_disabled_cache # :nodoc:
162
- Thread.current[:ar_prepared_statements_disabled_cache] ||= Set.new
181
+ ActiveSupport::IsolatedExecutionState[:active_record_prepared_statements_disabled_cache] ||= Set.new
163
182
  end
164
183
 
165
184
  class Version
@@ -201,8 +220,20 @@ module ActiveRecord
201
220
  @owner = Thread.current
202
221
  end
203
222
 
204
- def connection_klass # :nodoc:
205
- @pool.connection_klass
223
+ def connection_class # :nodoc:
224
+ @pool.connection_class
225
+ end
226
+
227
+ # The role (e.g. +:writing+) for the current connection. In a
228
+ # non-multi role application, +:writing+ is returned.
229
+ def role
230
+ @pool.role
231
+ end
232
+
233
+ # The shard (e.g. +:default+) for the current connection. In
234
+ # a non-sharded application, +:default+ is returned.
235
+ def shard
236
+ @pool.shard
206
237
  end
207
238
 
208
239
  def schema_cache
@@ -223,7 +254,7 @@ module ActiveRecord
223
254
  "Current thread: #{Thread.current}."
224
255
  end
225
256
 
226
- @idle_since = Concurrent.monotonic_time
257
+ @idle_since = Process.clock_gettime(Process::CLOCK_MONOTONIC)
227
258
  @owner = nil
228
259
  else
229
260
  raise ActiveRecordError, "Cannot expire connection, it is not currently leased."
@@ -246,7 +277,7 @@ module ActiveRecord
246
277
  # Seconds since this connection was returned to the pool
247
278
  def seconds_idle # :nodoc:
248
279
  return 0 if in_use?
249
- Concurrent.monotonic_time - @idle_since
280
+ Process.clock_gettime(Process::CLOCK_MONOTONIC) - @idle_since
250
281
  end
251
282
 
252
283
  def unprepared_statement
@@ -344,6 +375,11 @@ module ActiveRecord
344
375
  false
345
376
  end
346
377
 
378
+ # Does this adapter support creating deferrable constraints?
379
+ def supports_deferrable_constraints?
380
+ false
381
+ end
382
+
347
383
  # Does this adapter support creating check constraints?
348
384
  def supports_check_constraints?
349
385
  false
@@ -418,6 +454,15 @@ module ActiveRecord
418
454
  false
419
455
  end
420
456
 
457
+ def supports_concurrent_connections?
458
+ true
459
+ end
460
+
461
+ def async_enabled? # :nodoc:
462
+ supports_concurrent_connections? &&
463
+ !ActiveRecord.async_query_executor.nil? && !pool.async_executor.nil?
464
+ end
465
+
421
466
  # This is meant to be implemented by the adapters that support extensions
422
467
  def disable_extension(name)
423
468
  end
@@ -426,6 +471,10 @@ module ActiveRecord
426
471
  def enable_extension(name)
427
472
  end
428
473
 
474
+ # This is meant to be implemented by the adapters that support custom enum types
475
+ def create_enum(*) # :nodoc:
476
+ end
477
+
429
478
  def advisory_locks_enabled? # :nodoc:
430
479
  supports_advisory_locks? && @advisory_locks_enabled
431
480
  end
@@ -461,6 +510,11 @@ module ActiveRecord
461
510
  yield
462
511
  end
463
512
 
513
+ # Override to check all foreign key constraints in a database.
514
+ def all_foreign_keys_valid?
515
+ true
516
+ end
517
+
464
518
  # CONNECTION MANAGEMENT ====================================
465
519
 
466
520
  # Checks whether the connection to the database is still active. This includes
@@ -539,6 +593,10 @@ module ActiveRecord
539
593
  #
540
594
  # This is useful for when you need to call a proprietary method such as
541
595
  # PostgreSQL's lo_* methods.
596
+ #
597
+ # Active Record cannot track if the database is getting modified using
598
+ # this client. If that is the case, generally you'll want to invalidate
599
+ # the query cache using +ActiveRecord::Base.clear_query_cache+.
542
600
  def raw_connection
543
601
  disable_lazy_transactions!
544
602
  @connection
@@ -599,78 +657,93 @@ module ActiveRecord
599
657
  def check_version # :nodoc:
600
658
  end
601
659
 
602
- private
603
- def type_map
604
- @type_map ||= Type::TypeMap.new.tap do |mapping|
605
- initialize_type_map(mapping)
606
- end
660
+ # Returns the version identifier of the schema currently available in
661
+ # the database. This is generally equal to the number of the highest-
662
+ # numbered migration that has been executed, or 0 if no schema
663
+ # information is present / the database is empty.
664
+ def schema_version
665
+ migration_context.current_version
666
+ end
667
+
668
+ def field_ordered_value(column, values) # :nodoc:
669
+ node = Arel::Nodes::Case.new(column)
670
+ values.each.with_index(1) do |value, order|
671
+ node.when(value).then(order)
607
672
  end
608
673
 
609
- def initialize_type_map(m = type_map)
610
- register_class_with_limit m, %r(boolean)i, Type::Boolean
611
- register_class_with_limit m, %r(char)i, Type::String
612
- register_class_with_limit m, %r(binary)i, Type::Binary
613
- register_class_with_limit m, %r(text)i, Type::Text
614
- register_class_with_precision m, %r(date)i, Type::Date
615
- register_class_with_precision m, %r(time)i, Type::Time
616
- register_class_with_precision m, %r(datetime)i, Type::DateTime
617
- register_class_with_limit m, %r(float)i, Type::Float
618
- register_class_with_limit m, %r(int)i, Type::Integer
619
-
620
- m.alias_type %r(blob)i, "binary"
621
- m.alias_type %r(clob)i, "text"
622
- m.alias_type %r(timestamp)i, "datetime"
623
- m.alias_type %r(numeric)i, "decimal"
624
- m.alias_type %r(number)i, "decimal"
625
- m.alias_type %r(double)i, "float"
626
-
627
- m.register_type %r(^json)i, Type::Json.new
628
-
629
- m.register_type(%r(decimal)i) do |sql_type|
630
- scale = extract_scale(sql_type)
631
- precision = extract_precision(sql_type)
632
-
633
- if scale == 0
634
- # FIXME: Remove this class as well
635
- Type::DecimalWithoutScale.new(precision: precision)
636
- else
637
- Type::Decimal.new(precision: precision, scale: scale)
674
+ Arel::Nodes::Ascending.new(node.else(values.length + 1))
675
+ end
676
+
677
+ class << self
678
+ private
679
+ def initialize_type_map(m)
680
+ register_class_with_limit m, %r(boolean)i, Type::Boolean
681
+ register_class_with_limit m, %r(char)i, Type::String
682
+ register_class_with_limit m, %r(binary)i, Type::Binary
683
+ register_class_with_limit m, %r(text)i, Type::Text
684
+ register_class_with_precision m, %r(date)i, Type::Date
685
+ register_class_with_precision m, %r(time)i, Type::Time
686
+ register_class_with_precision m, %r(datetime)i, Type::DateTime
687
+ register_class_with_limit m, %r(float)i, Type::Float
688
+ register_class_with_limit m, %r(int)i, Type::Integer
689
+
690
+ m.alias_type %r(blob)i, "binary"
691
+ m.alias_type %r(clob)i, "text"
692
+ m.alias_type %r(timestamp)i, "datetime"
693
+ m.alias_type %r(numeric)i, "decimal"
694
+ m.alias_type %r(number)i, "decimal"
695
+ m.alias_type %r(double)i, "float"
696
+
697
+ m.register_type %r(^json)i, Type::Json.new
698
+
699
+ m.register_type(%r(decimal)i) do |sql_type|
700
+ scale = extract_scale(sql_type)
701
+ precision = extract_precision(sql_type)
702
+
703
+ if scale == 0
704
+ # FIXME: Remove this class as well
705
+ Type::DecimalWithoutScale.new(precision: precision)
706
+ else
707
+ Type::Decimal.new(precision: precision, scale: scale)
708
+ end
638
709
  end
639
710
  end
640
- end
641
711
 
642
- def reload_type_map
643
- type_map.clear
644
- initialize_type_map
645
- end
712
+ def register_class_with_limit(mapping, key, klass)
713
+ mapping.register_type(key) do |*args|
714
+ limit = extract_limit(args.last)
715
+ klass.new(limit: limit)
716
+ end
717
+ end
646
718
 
647
- def register_class_with_limit(mapping, key, klass)
648
- mapping.register_type(key) do |*args|
649
- limit = extract_limit(args.last)
650
- klass.new(limit: limit)
719
+ def register_class_with_precision(mapping, key, klass)
720
+ mapping.register_type(key) do |*args|
721
+ precision = extract_precision(args.last)
722
+ klass.new(precision: precision)
723
+ end
724
+ end
725
+
726
+ def extract_scale(sql_type)
727
+ case sql_type
728
+ when /\((\d+)\)/ then 0
729
+ when /\((\d+)(,(\d+))\)/ then $3.to_i
730
+ end
651
731
  end
652
- end
653
732
 
654
- def register_class_with_precision(mapping, key, klass)
655
- mapping.register_type(key) do |*args|
656
- precision = extract_precision(args.last)
657
- klass.new(precision: precision)
733
+ def extract_precision(sql_type)
734
+ $1.to_i if sql_type =~ /\((\d+)(,\d+)?\)/
658
735
  end
659
- end
660
736
 
661
- def extract_scale(sql_type)
662
- case sql_type
663
- when /\((\d+)\)/ then 0
664
- when /\((\d+)(,(\d+))\)/ then $3.to_i
737
+ def extract_limit(sql_type)
738
+ $1.to_i if sql_type =~ /\((.*)\)/
665
739
  end
666
- end
740
+ end
667
741
 
668
- def extract_precision(sql_type)
669
- $1.to_i if sql_type =~ /\((\d+)(,\d+)?\)/
670
- end
742
+ TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map(m) }
671
743
 
672
- def extract_limit(sql_type)
673
- $1.to_i if sql_type =~ /\((.*)\)/
744
+ private
745
+ def type_map
746
+ TYPE_MAP
674
747
  end
675
748
 
676
749
  def translate_exception_class(e, sql, binds)
@@ -683,7 +756,7 @@ module ActiveRecord
683
756
  exception
684
757
  end
685
758
 
686
- def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil) # :doc:
759
+ def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil, async: false, &block) # :doc:
687
760
  @instrumenter.instrument(
688
761
  "sql.active_record",
689
762
  sql: sql,
@@ -691,15 +764,21 @@ module ActiveRecord
691
764
  binds: binds,
692
765
  type_casted_binds: type_casted_binds,
693
766
  statement_name: statement_name,
767
+ async: async,
694
768
  connection: self) do
695
- @lock.synchronize do
696
- yield
697
- end
769
+ @lock.synchronize(&block)
698
770
  rescue => e
699
771
  raise translate_exception_class(e, sql, binds)
700
772
  end
701
773
  end
702
774
 
775
+ def transform_query(sql)
776
+ ActiveRecord.query_transformers.each do |transformer|
777
+ sql = transformer.call(sql)
778
+ end
779
+ sql
780
+ end
781
+
703
782
  def translate_exception(exception, message:, sql:, binds:)
704
783
  # override in derived class
705
784
  case exception